|
|
@ -29,8 +29,9 @@ import ( |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
var ( |
|
|
|
bigZero = new(big.Int) |
|
|
|
bigZero = new(big.Int) |
|
|
|
errWriteProtection = errors.New("evm: write protection") |
|
|
|
errWriteProtection = errors.New("evm: write protection") |
|
|
|
|
|
|
|
errReturnDataOutOfBounds = errors.New("evm: return data out of bounds") |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
@ -242,6 +243,7 @@ func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac |
|
|
|
evm.interpreter.intPool.put(y) |
|
|
|
evm.interpreter.intPool.put(y) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
x, y := stack.pop(), stack.pop() |
|
|
|
x, y := stack.pop(), stack.pop() |
|
|
|
stack.push(x.Or(x, y)) |
|
|
|
stack.push(x.Or(x, y)) |
|
|
@ -249,6 +251,7 @@ func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack |
|
|
|
evm.interpreter.intPool.put(y) |
|
|
|
evm.interpreter.intPool.put(y) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
x, y := stack.pop(), stack.pop() |
|
|
|
x, y := stack.pop(), stack.pop() |
|
|
|
stack.push(x.Xor(x, y)) |
|
|
|
stack.push(x.Xor(x, y)) |
|
|
@ -268,6 +271,7 @@ func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta |
|
|
|
evm.interpreter.intPool.put(th) |
|
|
|
evm.interpreter.intPool.put(th) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
x, y, z := stack.pop(), stack.pop(), stack.pop() |
|
|
|
x, y, z := stack.pop(), stack.pop(), stack.pop() |
|
|
|
if z.Cmp(bigZero) > 0 { |
|
|
|
if z.Cmp(bigZero) > 0 { |
|
|
@ -281,6 +285,7 @@ func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S |
|
|
|
evm.interpreter.intPool.put(y, z) |
|
|
|
evm.interpreter.intPool.put(y, z) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
x, y, z := stack.pop(), stack.pop(), stack.pop() |
|
|
|
x, y, z := stack.pop(), stack.pop(), stack.pop() |
|
|
|
if z.Cmp(bigZero) > 0 { |
|
|
|
if z.Cmp(bigZero) > 0 { |
|
|
@ -338,25 +343,47 @@ func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opCalldataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
stack.push(new(big.Int).SetBytes(getDataBig(contract.Input, stack.pop(), big32))) |
|
|
|
stack.push(new(big.Int).SetBytes(getDataBig(contract.Input, stack.pop(), big32))) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opCalldataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) |
|
|
|
stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opCalldataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
|
|
|
|
var ( |
|
|
|
|
|
|
|
memOffset = stack.pop() |
|
|
|
|
|
|
|
dataOffset = stack.pop() |
|
|
|
|
|
|
|
length = stack.pop() |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
evm.interpreter.intPool.put(memOffset, dataOffset, length) |
|
|
|
|
|
|
|
return nil, nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
|
|
|
|
stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData)))) |
|
|
|
|
|
|
|
return nil, nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
var ( |
|
|
|
var ( |
|
|
|
mOff = stack.pop() |
|
|
|
memOffset = stack.pop() |
|
|
|
cOff = stack.pop() |
|
|
|
dataOffset = stack.pop() |
|
|
|
l = stack.pop() |
|
|
|
length = stack.pop() |
|
|
|
) |
|
|
|
) |
|
|
|
memory.Set(mOff.Uint64(), l.Uint64(), getDataBig(contract.Input, cOff, l)) |
|
|
|
defer evm.interpreter.intPool.put(memOffset, dataOffset, length) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end := new(big.Int).Add(dataOffset, length) |
|
|
|
|
|
|
|
if end.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < end.Uint64() { |
|
|
|
|
|
|
|
return nil, errReturnDataOutOfBounds |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()]) |
|
|
|
|
|
|
|
|
|
|
|
evm.interpreter.intPool.put(mOff, cOff, l) |
|
|
|
|
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -378,31 +405,28 @@ func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack |
|
|
|
|
|
|
|
|
|
|
|
func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
var ( |
|
|
|
var ( |
|
|
|
mOff = stack.pop() |
|
|
|
memOffset = stack.pop() |
|
|
|
cOff = stack.pop() |
|
|
|
codeOffset = stack.pop() |
|
|
|
l = stack.pop() |
|
|
|
length = stack.pop() |
|
|
|
) |
|
|
|
) |
|
|
|
codeCopy := getDataBig(contract.Code, cOff, l) |
|
|
|
codeCopy := getDataBig(contract.Code, codeOffset, length) |
|
|
|
|
|
|
|
memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) |
|
|
|
|
|
|
|
|
|
|
|
memory.Set(mOff.Uint64(), l.Uint64(), codeCopy) |
|
|
|
evm.interpreter.intPool.put(memOffset, codeOffset, length) |
|
|
|
|
|
|
|
|
|
|
|
evm.interpreter.intPool.put(mOff, cOff, l) |
|
|
|
|
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
var ( |
|
|
|
var ( |
|
|
|
addr = common.BigToAddress(stack.pop()) |
|
|
|
addr = common.BigToAddress(stack.pop()) |
|
|
|
mOff = stack.pop() |
|
|
|
memOffset = stack.pop() |
|
|
|
cOff = stack.pop() |
|
|
|
codeOffset = stack.pop() |
|
|
|
l = stack.pop() |
|
|
|
length = stack.pop() |
|
|
|
) |
|
|
|
) |
|
|
|
codeCopy := getDataBig(evm.StateDB.GetCode(addr), cOff, l) |
|
|
|
codeCopy := getDataBig(evm.StateDB.GetCode(addr), codeOffset, length) |
|
|
|
|
|
|
|
memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) |
|
|
|
memory.Set(mOff.Uint64(), l.Uint64(), codeCopy) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
evm.interpreter.intPool.put(mOff, cOff, l) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
evm.interpreter.intPool.put(memOffset, codeOffset, length) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -507,6 +531,7 @@ func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta |
|
|
|
evm.interpreter.intPool.put(pos) |
|
|
|
evm.interpreter.intPool.put(pos) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
pos, cond := stack.pop(), stack.pop() |
|
|
|
pos, cond := stack.pop(), stack.pop() |
|
|
|
if cond.Sign() != 0 { |
|
|
|
if cond.Sign() != 0 { |
|
|
@ -522,6 +547,7 @@ func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *St |
|
|
|
evm.interpreter.intPool.put(pos, cond) |
|
|
|
evm.interpreter.intPool.put(pos, cond) |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|