mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Revert "account/abi: handle solidity panic revert (#27868)"
This reverts commit be49691dac.
This commit is contained in:
parent
145723203a
commit
e138a04b57
2 changed files with 12 additions and 56 deletions
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
@ -247,37 +246,17 @@ func (abi *ABI) HasReceive() bool {
|
||||||
// revertSelector is a special function selector for revert reason unpacking.
|
// revertSelector is a special function selector for revert reason unpacking.
|
||||||
var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]
|
var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]
|
||||||
|
|
||||||
// panicSelector is a special function selector for panic reason unpacking.
|
|
||||||
var panicSelector = crypto.Keccak256([]byte("Panic(uint256)"))[:4]
|
|
||||||
|
|
||||||
// panicReasons map is for readable panic codes
|
|
||||||
// see this linkage for the deails
|
|
||||||
// https://docs.soliditylang.org/en/v0.8.21/control-structures.html#panic-via-assert-and-error-via-require
|
|
||||||
// the reason string list is copied from ether.js
|
|
||||||
// https://github.com/ethers-io/ethers.js/blob/fa3a883ff7c88611ce766f58bdd4b8ac90814470/src.ts/abi/interface.ts#L207-L218
|
|
||||||
var panicReasons = map[uint64]string{
|
|
||||||
0x00: "generic panic",
|
|
||||||
0x01: "assert(false)",
|
|
||||||
0x11: "arithmetic underflow or overflow",
|
|
||||||
0x12: "division or modulo by zero",
|
|
||||||
0x21: "enum overflow",
|
|
||||||
0x22: "invalid encoded storage byte array accessed",
|
|
||||||
0x31: "out-of-bounds array access; popping on an empty array",
|
|
||||||
0x32: "out-of-bounds access of an array or bytesN",
|
|
||||||
0x41: "out of memory",
|
|
||||||
0x51: "uninitialized function",
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnpackRevert resolves the abi-encoded revert reason. According to the solidity
|
// UnpackRevert resolves the abi-encoded revert reason. According to the solidity
|
||||||
// spec https://solidity.readthedocs.io/en/latest/control-structures.html#revert,
|
// spec https://solidity.readthedocs.io/en/latest/control-structures.html#revert,
|
||||||
// the provided revert reason is abi-encoded as if it were a call to function
|
// the provided revert reason is abi-encoded as if it were a call to a function
|
||||||
// `Error(string)` or `Panic(uint256)`. So it's a special tool for it.
|
// `Error(string)`. So it's a special tool for it.
|
||||||
func UnpackRevert(data []byte) (string, error) {
|
func UnpackRevert(data []byte) (string, error) {
|
||||||
if len(data) < 4 {
|
if len(data) < 4 {
|
||||||
return "", errors.New("invalid data for unpacking")
|
return "", errors.New("invalid data for unpacking")
|
||||||
}
|
}
|
||||||
switch {
|
if !bytes.Equal(data[:4], revertSelector) {
|
||||||
case bytes.Equal(data[:4], revertSelector):
|
return "", errors.New("invalid data for unpacking")
|
||||||
|
}
|
||||||
typ, err := NewType("string", "", nil)
|
typ, err := NewType("string", "", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
@ -287,25 +266,4 @@ func UnpackRevert(data []byte) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return unpacked[0].(string), nil
|
return unpacked[0].(string), nil
|
||||||
case bytes.Equal(data[:4], panicSelector):
|
|
||||||
typ, err := NewType("uint256", "", nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:])
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
pCode := unpacked[0].(*big.Int)
|
|
||||||
// uint64 safety check for future
|
|
||||||
// but the code is not bigger than MAX(uint64) now
|
|
||||||
if pCode.IsUint64() {
|
|
||||||
if reason, ok := panicReasons[pCode.Uint64()]; ok {
|
|
||||||
return reason, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("unknown panic code: %#x", pCode), nil
|
|
||||||
default:
|
|
||||||
return "", errors.New("invalid data for unpacking")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1173,8 +1173,6 @@ func TestUnpackRevert(t *testing.T) {
|
||||||
{"", "", errors.New("invalid data for unpacking")},
|
{"", "", errors.New("invalid data for unpacking")},
|
||||||
{"08c379a1", "", errors.New("invalid data for unpacking")},
|
{"08c379a1", "", errors.New("invalid data for unpacking")},
|
||||||
{"08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000", "revert reason", nil},
|
{"08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000", "revert reason", nil},
|
||||||
{"4e487b710000000000000000000000000000000000000000000000000000000000000000", "generic panic", nil},
|
|
||||||
{"4e487b7100000000000000000000000000000000000000000000000000000000000000ff", "unknown panic code: 0xff", nil},
|
|
||||||
}
|
}
|
||||||
for index, c := range cases {
|
for index, c := range cases {
|
||||||
t.Run(fmt.Sprintf("case %d", index), func(t *testing.T) {
|
t.Run(fmt.Sprintf("case %d", index), func(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue