github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/vm/memory.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:36</date> 10 //</624450083005403136> 11 12 13 package vm 14 15 import ( 16 "fmt" 17 "math/big" 18 19 "github.com/ethereum/go-ethereum/common/math" 20 ) 21 22 //内存为以太坊虚拟机实现了一个简单的内存模型。 23 type Memory struct { 24 store []byte 25 lastGasCost uint64 26 } 27 28 //new memory返回新的内存模型。 29 func NewMemory() *Memory { 30 return &Memory{} 31 } 32 33 //将“设置偏移量+大小”设置为“值” 34 func (m *Memory) Set(offset, size uint64, value []byte) { 35 //偏移量可能大于0,大小等于0。这是因为 36 //当大小为零(no-op)时,CalcMemsize(common.go)可能返回0。 37 if size > 0 { 38 //存储长度不能小于偏移量+大小。 39 //在设置内存之前,应调整存储的大小 40 if offset+size > uint64(len(m.store)) { 41 panic("invalid memory: store empty") 42 } 43 copy(m.store[offset:offset+size], value) 44 } 45 } 46 47 //set32将从偏移量开始的32个字节设置为val值,用零左填充到 48 //32字节。 49 func (m *Memory) Set32(offset uint64, val *big.Int) { 50 //存储长度不能小于偏移量+大小。 51 //在设置内存之前,应调整存储的大小 52 if offset+32 > uint64(len(m.store)) { 53 panic("invalid memory: store empty") 54 } 55 //把记忆区归零 56 copy(m.store[offset:offset+32], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) 57 //填写相关位 58 math.ReadBits(val, m.store[offset:offset+32]) 59 } 60 61 //调整大小将内存大小调整为 62 func (m *Memory) Resize(size uint64) { 63 if uint64(m.Len()) < size { 64 m.store = append(m.store, make([]byte, size-uint64(m.Len()))...) 65 } 66 } 67 68 //get返回偏移量+作为新切片的大小 69 func (m *Memory) Get(offset, size int64) (cpy []byte) { 70 if size == 0 { 71 return nil 72 } 73 74 if len(m.store) > int(offset) { 75 cpy = make([]byte, size) 76 copy(cpy, m.store[offset:offset+size]) 77 78 return 79 } 80 81 return 82 } 83 84 //getptr返回偏移量+大小 85 func (m *Memory) GetPtr(offset, size int64) []byte { 86 if size == 0 { 87 return nil 88 } 89 90 if len(m.store) > int(offset) { 91 return m.store[offset : offset+size] 92 } 93 94 return nil 95 } 96 97 //len返回背衬片的长度 98 func (m *Memory) Len() int { 99 return len(m.store) 100 } 101 102 //数据返回备份切片 103 func (m *Memory) Data() []byte { 104 return m.store 105 } 106 107 //打印转储内存的内容。 108 func (m *Memory) Print() { 109 fmt.Printf("### mem %d bytes ###\n", len(m.store)) 110 if len(m.store) > 0 { 111 addr := 0 112 for i := 0; i+32 <= len(m.store); i += 32 { 113 fmt.Printf("%03d: % x\n", addr, m.store[i:i+32]) 114 addr++ 115 } 116 } else { 117 fmt.Println("-- empty --") 118 } 119 fmt.Println("####################") 120 } 121