diff --git a/deploy/jobs/jobs_contracts.go b/deploy/jobs/jobs_contracts.go index 38a7d2b1a49edd29d5767621eeb843aecab58c75..6a8e1e86098e495054ae147a7ac738c26b20fa50 100644 --- a/deploy/jobs/jobs_contracts.go +++ b/deploy/jobs/jobs_contracts.go @@ -396,8 +396,13 @@ func CallJob(call *def.Call, do *def.Packages) (string, []*abi.Variable, error) if err != nil { return "", nil, err } - log.WithField("Revert Message", message).Error("transaction reverted") - return message, nil, txe.Exception.AsError() + if message != nil { + log.WithField("Revert Reason", *message).Error("Transaction reverted with reason") + return *message, nil, txe.Exception.AsError() + } else { + log.Error("Transaction reverted with no reason") + return "", nil, txe.Exception.AsError() + } } var result string log.Debug(txe.Result.Return) diff --git a/execution/evm/abi/abi.go b/execution/evm/abi/abi.go index 0dea5213413516524b8f34bb248a80806938723f..3d8d3f9674e05ff3543c685f8349dc1de5289c63 100644 --- a/execution/evm/abi/abi.go +++ b/execution/evm/abi/abi.go @@ -1019,8 +1019,14 @@ func GetFunctionID(signature string) (id FunctionID) { return } -func UnpackRevert(data []byte) (message string, err error) { - err = RevertAbi.UnpackWithID(data, &message) +// UnpackRevert decodes the revert reason if a contract called revert. If no +// reason was given, message will be nil else it will point to the string +func UnpackRevert(data []byte) (message *string, err error) { + if len(data) > 0 { + var msg string + err = RevertAbi.UnpackWithID(data, &msg) + message = &msg + } return } diff --git a/execution/solidity/revert.sol b/execution/solidity/revert.sol index dc19b5ebb9c9eb3868b32f280929e6d9851b3ced..67a48c51e8391646ae8ce61e02c7beb0c80b096d 100644 --- a/execution/solidity/revert.sol +++ b/execution/solidity/revert.sol @@ -12,4 +12,8 @@ contract Revert { this.RevertAt(i); } } + + function RevertNoReason() pure public { + revert(); + } } \ No newline at end of file diff --git a/execution/solidity/revert.sol.go b/execution/solidity/revert.sol.go index 2d618b950405fcee6b7bb92564677431bbb4ec65..11eaaedfb2a4611738dd7b481551f582f18f420d 100644 --- a/execution/solidity/revert.sol.go +++ b/execution/solidity/revert.sol.go @@ -2,5 +2,5 @@ package solidity import "github.com/tmthrgd/go-hex" -var Bytecode_Revert = hex.MustDecodeString("608060405234801561001057600080fd5b506101f4806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635b202afb14610046575b600080fd5b34801561005257600080fd5b50610077600480360381019080803563ffffffff169060200190929190505050610079565b005b60008163ffffffff1614156100f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f492068617665207265766572746564000000000000000000000000000000000081525060200191505060405180910390fd5b8080600190039150508063ffffffff167ff7f0feb5b4ac5276c55faa8936d962de931ebe8333a2efdc0506878de3979ba960405160405180910390a23073ffffffffffffffffffffffffffffffffffffffff16635b202afb826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808263ffffffff1663ffffffff168152602001915050600060405180830381600087803b1580156101ad57600080fd5b505af11580156101c1573d6000803e3d6000fd5b50505050505600a165627a7a7230582024a36efd1abf70d00acdeea9b7cebd6e23cb5739c56ac17f65054c1d5711e9bf0029") -var Abi_Revert = []byte(`[{"constant":false,"inputs":[{"name":"i","type":"uint32"}],"name":"RevertAt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"i","type":"uint32"}],"name":"NotReverting","type":"event"}]`) +var Bytecode_Revert = hex.MustDecodeString("608060405234801561001057600080fd5b5061021b806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635b202afb146100515780636037b04c14610084575b600080fd5b34801561005d57600080fd5b50610082600480360381019080803563ffffffff16906020019092919050505061009b565b005b34801561009057600080fd5b506100996101ea565b005b60008163ffffffff161415610118576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f492068617665207265766572746564000000000000000000000000000000000081525060200191505060405180910390fd5b8080600190039150508063ffffffff167ff7f0feb5b4ac5276c55faa8936d962de931ebe8333a2efdc0506878de3979ba960405160405180910390a23073ffffffffffffffffffffffffffffffffffffffff16635b202afb826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808263ffffffff1663ffffffff168152602001915050600060405180830381600087803b1580156101cf57600080fd5b505af11580156101e3573d6000803e3d6000fd5b5050505050565b600080fd00a165627a7a72305820ff4434dee89042421ea97df306f10c834b29cf641ad0c50ff83463b68c78ddf00029") +var Abi_Revert = []byte(`[{"constant":false,"inputs":[{"name":"i","type":"uint32"}],"name":"RevertAt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"RevertNoReason","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"i","type":"uint32"}],"name":"NotReverting","type":"event"}]`) diff --git a/integration/rpctransact/call_test.go b/integration/rpctransact/call_test.go index fe46a98d271739dd2e62f83dc03b61dc50e808bf..26f7f0e4ceb56f5a0e281b1d17ed530dd81f559b 100644 --- a/integration/rpctransact/call_test.go +++ b/integration/rpctransact/call_test.go @@ -366,7 +366,22 @@ func TestRevert(t *testing.T) { assert.Equal(t, errors.ErrorCodeExecutionReverted, txe.Exception.Code) revertReason, err := abi.UnpackRevert(txe.Result.Return) require.NoError(t, err) - assert.Equal(t, revertReason, "I have reverted") + assert.Equal(t, *revertReason, "I have reverted") +} + +func TestRevertWithoutReason(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + txe := rpctest.CreateContract(t, cli, inputAddress, solidity.Bytecode_Revert) + spec, err := abi.ReadAbiSpec(solidity.Abi_Revert) + require.NoError(t, err) + data, err := spec.Pack("RevertNoReason") + require.NoError(t, err) + txe = rpctest.CallContract(t, cli, inputAddress, txe.Receipt.ContractAddress, data) + assert.Equal(t, errors.ErrorCodeExecutionReverted, txe.Exception.Code) + fmt.Printf("%x\n", txe.Result.Return) + revertReason, err := abi.UnpackRevert(txe.Result.Return) + require.NoError(t, err) + assert.Nil(t, revertReason) } func filterCalls(evs []*exec.Event) []*exec.CallEvent {