diff --git a/ethvm/types.go b/ethvm/types.go index bb67359931..9cddd7c33f 100644 --- a/ethvm/types.go +++ b/ethvm/types.go @@ -49,6 +49,8 @@ const ( CODESIZE = 0x38 CODECOPY = 0x39 GASPRICE = 0x3a + EXTCODECOPY = 0x3b + EXTCODESIZE = 0x3c // 0x40 range - block operations PREVHASH = 0x40 @@ -142,10 +144,11 @@ const ( SWAP16 = 0x9f // 0xf0 range - closures - CREATE = 0xf0 - CALL = 0xf1 - RETURN = 0xf2 - POST = 0xf3 + CREATE = 0xf0 + CALL = 0xf1 + RETURN = 0xf2 + POST = 0xf3 + CALLSTATELESS = 0xf4 // 0x70 range - other LOG = 0xfe // XXX Unofficial @@ -197,12 +200,14 @@ var opCodeToString = map[OpCode]string{ GASPRICE: "TXGASPRICE", // 0x40 range - block operations - PREVHASH: "PREVHASH", - COINBASE: "COINBASE", - TIMESTAMP: "TIMESTAMP", - NUMBER: "NUMBER", - DIFFICULTY: "DIFFICULTY", - GASLIMIT: "GASLIMIT", + PREVHASH: "PREVHASH", + COINBASE: "COINBASE", + TIMESTAMP: "TIMESTAMP", + NUMBER: "NUMBER", + DIFFICULTY: "DIFFICULTY", + GASLIMIT: "GASLIMIT", + EXTCODESIZE: "EXTCODESIZE", + EXTCODECOPY: "EXTCODECOPY", // 0x50 range - 'storage' and execution POP: "POP", @@ -288,9 +293,11 @@ var opCodeToString = map[OpCode]string{ SWAP16: "SWAP16", // 0xf0 range - CREATE: "CREATE", - CALL: "CALL", - RETURN: "RETURN", + CREATE: "CREATE", + CALL: "CALL", + RETURN: "RETURN", + POST: "POST", + CALLSTATELESS: "CALLSTATELESS", // 0x70 range - other LOG: "LOG", @@ -343,7 +350,12 @@ var OpCodes = map[string]byte{ "CALLVALUE": 0x34, "CALLDATALOAD": 0x35, "CALLDATASIZE": 0x36, - "GASPRICE": 0x38, + "CALLDATACOPY": 0x37, + "CODESIZE": 0x38, + "CODECOPY": 0x39, + "GASPRICE": 0x3a, + "EXTCODECOPY": 0x3b, + "EXTCODESIZE": 0x3c, // 0x40 range - block operations "PREVHASH": 0x40, @@ -436,10 +448,11 @@ var OpCodes = map[string]byte{ "SWAP16": 0x9f, // 0xf0 range - closures - "CREATE": 0xf0, - "CALL": 0xf1, - "RETURN": 0xf2, - "POST": 0xf3, + "CREATE": 0xf0, + "CALL": 0xf1, + "RETURN": 0xf2, + "POST": 0xf3, + "CALLSTATELESS": 0xf4, // 0x70 range - other "LOG": 0xfe, diff --git a/ethvm/vm.go b/ethvm/vm.go index 924a861ca2..2acf52f92c 100644 --- a/ethvm/vm.go +++ b/ethvm/vm.go @@ -197,6 +197,10 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { require(3) newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64() + case EXTCODECOPY: + require(4) + + newMemSize = stack.data[stack.Len()-1].Uint64() + stack.data[stack.Len()-4].Uint64() case CALL: require(7) gas.Set(GasCall) @@ -550,14 +554,32 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { code := closure.Args[cOff : cOff+l] mem.Set(mOff, l, code) - case CODESIZE: - l := big.NewInt(int64(len(closure.Code))) + case CODESIZE, EXTCODESIZE: + var code []byte + if op == EXTCODECOPY { + addr := stack.Pop().Bytes() + + code = self.env.State().GetCode(addr) + } else { + code = closure.Code + } + + l := big.NewInt(int64(len(code))) stack.Push(l) self.Printf(" => %d", l) - case CODECOPY: + case CODECOPY, EXTCODECOPY: + var code []byte + if op == EXTCODECOPY { + addr := stack.Pop().Bytes() + + code = self.env.State().GetCode(addr) + } else { + code = closure.Code + } + var ( - size = int64(len(closure.Code)) + size = int64(len(code)) mOff = stack.Pop().Int64() cOff = stack.Pop().Int64() l = stack.Pop().Int64() @@ -570,9 +592,9 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { l = 0 } - code := closure.Code[cOff : cOff+l] + codeCopy := code[cOff : cOff+l] - mem.Set(mOff, l, code) + mem.Set(mOff, l, codeCopy) case GASPRICE: stack.Push(closure.Price)