aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2020-07-02 01:36:18 -0400
committerDeterminant <[email protected]>2020-07-02 01:36:18 -0400
commitca6847998d867dc5d66e76a03bda9c72ae8d287b (patch)
treec6eb50a6e8c2d441d77468492c797c6c59885c46
parent2d396b3c69a26e4096ccb376c012911d299c68c7 (diff)
make MultiCoin.transfer work
-rw-r--r--core/vm/interpreter.go2
-rw-r--r--core/vm/jump_table.go3
-rw-r--r--core/vm/memory_table.go16
-rw-r--r--examples/multicoin/main.go10
-rw-r--r--examples/multicoin/mc_test.sol8
5 files changed, 34 insertions, 5 deletions
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 007e5e3..3d388d6 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -220,7 +220,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// for a call operation is the value. Transferring value from one
// account to the others means the state is modified and should also
// return with an error.
- if operation.writes || (op == CALL && stack.Back(2).Sign() != 0) {
+ if operation.writes || ((op == CALL || op == CALLEX) && stack.Back(2).Sign() != 0) {
return nil, errWriteProtection
}
}
diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go
index 359b753..737dd14 100644
--- a/core/vm/jump_table.go
+++ b/core/vm/jump_table.go
@@ -183,6 +183,7 @@ func newTangerineWhistleInstructionSet() JumpTable {
instructionSet[SLOAD].constantGas = params.SloadGasEIP150
instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150
instructionSet[CALL].constantGas = params.CallGasEIP150
+ instructionSet[CALLEX].constantGas = params.CallGasEIP150
instructionSet[CALLCODE].constantGas = params.CallGasEIP150
instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150
return instructionSet
@@ -1147,7 +1148,7 @@ func newFrontierInstructionSet() JumpTable {
dynamicGas: gasCall,
minStack: minStack(9, 1),
maxStack: maxStack(9, 1),
- memorySize: memoryCall,
+ memorySize: memoryCallExpert,
valid: true,
returns: true,
},
diff --git a/core/vm/memory_table.go b/core/vm/memory_table.go
index 4fcb414..047f610 100644
--- a/core/vm/memory_table.go
+++ b/core/vm/memory_table.go
@@ -70,6 +70,22 @@ func memoryCall(stack *Stack) (uint64, bool) {
}
return y, false
}
+
+func memoryCallExpert(stack *Stack) (uint64, bool) {
+ x, overflow := calcMemSize64(stack.Back(7), stack.Back(8))
+ if overflow {
+ return 0, true
+ }
+ y, overflow := calcMemSize64(stack.Back(5), stack.Back(6))
+ if overflow {
+ return 0, true
+ }
+ if x > y {
+ return x, false
+ }
+ return y, false
+}
+
func memoryDelegateCall(stack *Stack) (uint64, bool) {
x, overflow := calcMemSize64(stack.Back(4), stack.Back(5))
if overflow {
diff --git a/examples/multicoin/main.go b/examples/multicoin/main.go
index 9d1970a..403db4d 100644
--- a/examples/multicoin/main.go
+++ b/examples/multicoin/main.go
@@ -55,7 +55,7 @@ func main() {
bob, _ := coreth.NewKey(rand.Reader)
g := new(core.Genesis)
- b := `{"config":{"chainId":1,"homesteadBlock":0,"daoForkBlock":0,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0},"nonce":"0x0","timestamp":"0x0","extraData":"0x00","gasLimit":"0x5f5e100","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","alloc":{"751a0b96e1042bee789452ecb20253fba40dbe85":{"balance":"0x1000000000000000", "mcbalance": {"0x0000000000000000000000000000000000000000000000000000000000000000": 1000000000000000000}}, "0100000000000000000000000000000000000000": {"code": "0x730000000000000000000000000000000000000000301460806040526004361061004b5760003560e01c80631e01043914610050578063abb24ba014610092578063b6510bb3146100a9575b600080fd5b61007c6004803603602081101561006657600080fd5b8101908080359060200190929190505050610118565b6040518082815260200191505060405180910390f35b81801561009e57600080fd5b506100a761013b565b005b8180156100b557600080fd5b50610116600480360360808110156100cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061013e565b005b60003073ffffffffffffffffffffffffffffffffffffffff1682905d9050919050565b5c565b8373ffffffffffffffffffffffffffffffffffffffff1681836108fc8690811502906040516000604051808303818888878c8af69550505050505015801561018a573d6000803e3d6000fd5b505050505056fea26469706673582212200bc9fda886770285cc0f33cf0c674c080debc2ad79572ecf0c9f20d729b9487264736f6c634300060a0033", "balance": "0x0", "mcbalance": {}}},"number":"0x0","gasUsed":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`
+ b := `{"config":{"chainId":1,"homesteadBlock":0,"daoForkBlock":0,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0},"nonce":"0x0","timestamp":"0x0","extraData":"0x00","gasLimit":"0x5f5e100","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","alloc":{"751a0b96e1042bee789452ecb20253fba40dbe85":{"balance":"0x1000000000000000", "mcbalance": {"0x0000000000000000000000000000000000000000000000000000000000000000": 1000000000000000000}}, "0100000000000000000000000000000000000000": {"code": "0x730000000000000000000000000000000000000000301460806040526004361061004b5760003560e01c80631e01043914610050578063abb24ba014610092578063b6510bb3146100a9575b600080fd5b61007c6004803603602081101561006657600080fd5b8101908080359060200190929190505050610118565b6040518082815260200191505060405180910390f35b81801561009e57600080fd5b506100a761013b565b005b8180156100b557600080fd5b50610116600480360360808110156100cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061013e565b005b60003073ffffffffffffffffffffffffffffffffffffffff1682905d9050919050565b5c565b8373ffffffffffffffffffffffffffffffffffffffff1681836108fc8690811502906040516000604051808303818888878c8af69550505050505015801561018a573d6000803e3d6000fd5b505050505056fea2646970667358221220ed2100d6623a884d196eceefabe5e03da4309a2562bb25262f3874f1acb31cd764736f6c634300060a0033", "balance": "0x0", "mcbalance": {}}},"number":"0x0","gasUsed":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`
k := "0xabd71b35d559563fea757f0f5edbde286fb8c043105b15abb7cd57189306d7d1"
err := json.Unmarshal([]byte(b), g)
checkError(err)
@@ -149,15 +149,19 @@ func main() {
chain.AddRemoteTxs([]*types.Transaction{signedTx})
nonce++
}
- code, err = a.Pack("updateBalance", big.NewInt(0))
+ code, err = a.Pack("withdraw", big.NewInt(0), big.NewInt(0), big.NewInt(10000000000000000))
tx = types.NewTransaction(nonce, contractAddr, big.NewInt(0), uint64(gasLimit), gasPrice, code)
signedTx, err = types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey)
checkError(err)
chain.AddRemoteTxs([]*types.Transaction{signedTx})
nonce++
+ code, err = a.Pack("updateBalance", big.NewInt(0))
+ tx = types.NewTransaction(nonce, contractAddr, big.NewInt(0), uint64(gasLimit), gasPrice, code)
+ signedTx, err = types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey)
checkError(err)
-
+ chain.AddRemoteTxs([]*types.Transaction{signedTx})
+ nonce++
}()
}
return false
diff --git a/examples/multicoin/mc_test.sol b/examples/multicoin/mc_test.sol
index a7d468e..bfd42a5 100644
--- a/examples/multicoin/mc_test.sol
+++ b/examples/multicoin/mc_test.sol
@@ -16,4 +16,12 @@ contract MCTest {
}
function deposit() public payable {}
+
+ function withdraw(uint256 amount, uint256 coinid, uint256 amount2) public {
+ (bool success,) = MultiCoin.delegatecall(
+ abi.encodeWithSignature("transfer(address,uint256,uint256,uint256)",
+ msg.sender, amount, coinid, amount2));
+
+ require(success);
+ }
}