Improve parsing of ETH input data
This commit is contained in:
parent
5652ca6b2e
commit
a81420fc94
@ -76,7 +76,8 @@ func decamel(s string) string {
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
b.WriteRune(v)
|
||||
splittable = unicode.IsLower(v) || unicode.IsNumber(v)
|
||||
// special handling of ETH to be able to convert "addETHToContract" to "Add ETH To Contract"
|
||||
splittable = unicode.IsLower(v) || unicode.IsNumber(v) || (i >= 2 && s[i-2:i+1] == "ETH")
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
@ -98,7 +99,7 @@ func GetSignatureFromData(data string) uint32 {
|
||||
|
||||
const ErrorTy byte = 255
|
||||
|
||||
func processParam(data string, index int, t *abi.Type, processed []bool) ([]string, int, bool) {
|
||||
func processParam(data string, index int, dataOffset int, t *abi.Type, processed []bool) ([]string, int, bool) {
|
||||
var retval []string
|
||||
d := index << 6
|
||||
if d+64 > len(data) {
|
||||
@ -140,7 +141,7 @@ func processParam(data string, index int, t *abi.Type, processed []bool) ([]stri
|
||||
for i := 0; i < t.Size; i++ {
|
||||
var r []string
|
||||
var ok bool
|
||||
r, index, ok = processParam(data, index, t.Elem, processed)
|
||||
r, index, ok = processParam(data, index, dataOffset, t.Elem, processed)
|
||||
if !ok {
|
||||
return nil, 0, false
|
||||
}
|
||||
@ -156,7 +157,7 @@ func processParam(data string, index int, t *abi.Type, processed []bool) ([]stri
|
||||
processed[index] = true
|
||||
index++
|
||||
offset <<= 1
|
||||
d = int(offset)
|
||||
d = int(offset) + dataOffset
|
||||
dynIndex := d >> 6
|
||||
if d+64 > len(data) || d < 0 {
|
||||
return nil, 0, false
|
||||
@ -195,10 +196,11 @@ func processParam(data string, index int, t *abi.Type, processed []bool) ([]stri
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newOffset := dataOffset + dynIndex<<6
|
||||
for i := 0; i < count; i++ {
|
||||
var r []string
|
||||
var ok bool
|
||||
r, dynIndex, ok = processParam(data, dynIndex, t.Elem, processed)
|
||||
r, dynIndex, ok = processParam(data, dynIndex, newOffset, t.Elem, processed)
|
||||
if !ok {
|
||||
return nil, 0, false
|
||||
}
|
||||
@ -222,7 +224,7 @@ func tryParseParams(data string, params []string, parsedParams []abi.Type) []bch
|
||||
var ok bool
|
||||
for i := range params {
|
||||
t := &parsedParams[i]
|
||||
values, index, ok = processParam(data, index, t, processed)
|
||||
values, index, ok = processParam(data, index, 0, t, processed)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
@ -244,7 +246,7 @@ func ParseInputData(signatures *[]bchain.FourByteSignature, data string) *bchain
|
||||
if len(data) <= 2 { // data is empty or 0x
|
||||
return &bchain.EthereumParsedInputData{Name: "Transfer"}
|
||||
}
|
||||
if len(data) < 10 || (len(data)-10)%64 != 0 {
|
||||
if len(data) < 10 {
|
||||
return nil
|
||||
}
|
||||
parsed := bchain.EthereumParsedInputData{
|
||||
|
||||
@ -112,7 +112,7 @@ func TestParseInputData(t *testing.T) {
|
||||
Parameters: []string{"address"},
|
||||
},
|
||||
{
|
||||
Name: "addLiquidityETH",
|
||||
Name: "addLiquidityETHToContract",
|
||||
Parameters: []string{"address", "uint256", "uint256", "uint256", "address", "uint256"},
|
||||
},
|
||||
{
|
||||
@ -131,6 +131,10 @@ func TestParseInputData(t *testing.T) {
|
||||
Name: "transmitAndSellTokenForEth",
|
||||
Parameters: []string{"address", "uint256", "uint256", "uint256", "address", "(uint8,bytes32,bytes32)", "bytes"},
|
||||
},
|
||||
{
|
||||
Name: "execute",
|
||||
Parameters: []string{"bytes", "bytes[]", "uint256"},
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -191,13 +195,13 @@ func TestParseInputData(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "addLiquidityETH",
|
||||
name: "addLiquidityETHToContract",
|
||||
signatures: &signatures,
|
||||
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f400000000000000000000000000000000000000000000000000000000623f56f8",
|
||||
want: &bchain.EthereumParsedInputData{
|
||||
MethodId: "0xf305d719",
|
||||
Name: "Add Liquidity ETH",
|
||||
Function: "addLiquidityETH(address, uint256, uint256, uint256, address, uint256)",
|
||||
Name: "Add Liquidity ETH To Contract",
|
||||
Function: "addLiquidityETHToContract(address, uint256, uint256, uint256, address, uint256)",
|
||||
Params: []bchain.EthereumParsedInputParam{
|
||||
{
|
||||
Type: "address",
|
||||
@ -227,7 +231,7 @@ func TestParseInputData(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "addLiquidityETH data don't match - too long",
|
||||
name: "addLiquidityETHToContract data don't match - too long",
|
||||
signatures: &signatures,
|
||||
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f400000000000000000000000000000000000000000000000000000000623f56f800000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
want: &bchain.EthereumParsedInputData{
|
||||
@ -235,7 +239,7 @@ func TestParseInputData(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "addLiquidityETH data don't match - too short",
|
||||
name: "addLiquidityETHToContract data don't match - too short",
|
||||
signatures: &signatures,
|
||||
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f4",
|
||||
want: &bchain.EthereumParsedInputData{
|
||||
@ -362,6 +366,57 @@ func TestParseInputData(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "execute",
|
||||
signatures: &signatures,
|
||||
data: "0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000063fd167b00000000000000000000000000000000000000000000000000000000000000010800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000021e19e0c9bab2400000000000000000000000000000000000000000000000000000000000002fa5e9a300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cda4e840411c00a614ad9205caec807c7458a0e3000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
|
||||
want: &bchain.EthereumParsedInputData{
|
||||
MethodId: "0x3593564c",
|
||||
Name: "Execute",
|
||||
Function: "execute(bytes, bytes[], uint256)",
|
||||
Params: []bchain.EthereumParsedInputParam{
|
||||
{
|
||||
Type: "bytes",
|
||||
Values: []string{"0x08"},
|
||||
},
|
||||
{
|
||||
Type: "bytes[]",
|
||||
Values: []string{"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000021e19e0c9bab2400000000000000000000000000000000000000000000000000000000000002fa5e9a300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cda4e840411c00a614ad9205caec807c7458a0e3000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"},
|
||||
},
|
||||
{
|
||||
Type: "uint256",
|
||||
Values: []string{"1677530747"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "execute2",
|
||||
signatures: &signatures,
|
||||
data: "0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000063ffd82300000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000491478480c282e75df8b5700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f0f9d895aca5c8678f706fb8216fa22957685a13",
|
||||
want: &bchain.EthereumParsedInputData{
|
||||
MethodId: "0x3593564c",
|
||||
Name: "Execute",
|
||||
Function: "execute(bytes, bytes[], uint256)",
|
||||
Params: []bchain.EthereumParsedInputParam{
|
||||
{
|
||||
Type: "bytes",
|
||||
Values: []string{"0x0b08"},
|
||||
},
|
||||
{
|
||||
Type: "bytes[]",
|
||||
Values: []string{
|
||||
"0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000006f05b59d3b20000",
|
||||
"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000491478480c282e75df8b5700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f0f9d895aca5c8678f706fb8216fa22957685a13",
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: "uint256",
|
||||
Values: []string{"1677711395"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user