Skip to content

Commit 57a3fab

Browse files
authored
accounts/abi: fix resolving single struct argument (#23573)
1 parent ca9bce9 commit 57a3fab

File tree

3 files changed

+83
-8
lines changed

3 files changed

+83
-8
lines changed

accounts/abi/argument.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{
137137
dst := reflect.ValueOf(v).Elem()
138138
src := reflect.ValueOf(marshalledValues)
139139

140-
if dst.Kind() == reflect.Struct && src.Kind() != reflect.Struct {
140+
if dst.Kind() == reflect.Struct {
141141
return set(dst.Field(0), src)
142142
}
143143
return set(dst, src)

accounts/abi/bind/bind_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,77 @@ var bindTests = []struct {
17851785
nil,
17861786
nil,
17871787
},
1788+
// Test resolving single struct argument
1789+
{
1790+
`NewSingleStructArgument`,
1791+
`
1792+
pragma solidity ^0.8.0;
1793+
1794+
contract NewSingleStructArgument {
1795+
struct MyStruct{
1796+
uint256 a;
1797+
uint256 b;
1798+
}
1799+
event StructEvent(MyStruct s);
1800+
function TestEvent() public {
1801+
emit StructEvent(MyStruct({a: 1, b: 2}));
1802+
}
1803+
}
1804+
`,
1805+
[]string{"608060405234801561001057600080fd5b50610113806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806324ec1d3f14602d575b600080fd5b60336035565b005b7fb4b2ff75e30cb4317eaae16dd8a187dd89978df17565104caa6c2797caae27d460405180604001604052806001815260200160028152506040516078919060ba565b60405180910390a1565b6040820160008201516096600085018260ad565b50602082015160a7602085018260ad565b50505050565b60b48160d3565b82525050565b600060408201905060cd60008301846082565b92915050565b600081905091905056fea26469706673582212208823628796125bf9941ce4eda18da1be3cf2931b231708ab848e1bd7151c0c9a64736f6c63430008070033"},
1806+
[]string{`[{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"indexed":false,"internalType":"struct Test.MyStruct","name":"s","type":"tuple"}],"name":"StructEvent","type":"event"},{"inputs":[],"name":"TestEvent","outputs":[],"stateMutability":"nonpayable","type":"function"}]`},
1807+
`
1808+
"math/big"
1809+
1810+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
1811+
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
1812+
"github.com/ethereum/go-ethereum/core"
1813+
"github.com/ethereum/go-ethereum/crypto"
1814+
"github.com/ethereum/go-ethereum/eth/ethconfig"
1815+
`,
1816+
`
1817+
var (
1818+
key, _ = crypto.GenerateKey()
1819+
user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
1820+
sim = backends.NewSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
1821+
)
1822+
defer sim.Close()
1823+
1824+
_, _, d, err := DeployNewSingleStructArgument(user, sim)
1825+
if err != nil {
1826+
t.Fatalf("Failed to deploy contract %v", err)
1827+
}
1828+
sim.Commit()
1829+
1830+
_, err = d.TestEvent(user)
1831+
if err != nil {
1832+
t.Fatalf("Failed to call contract %v", err)
1833+
}
1834+
sim.Commit()
1835+
1836+
it, err := d.FilterStructEvent(nil)
1837+
if err != nil {
1838+
t.Fatalf("Failed to filter contract event %v", err)
1839+
}
1840+
var count int
1841+
for it.Next() {
1842+
if it.Event.S.A.Cmp(big.NewInt(1)) != 0 {
1843+
t.Fatal("Unexpected contract event")
1844+
}
1845+
if it.Event.S.B.Cmp(big.NewInt(2)) != 0 {
1846+
t.Fatal("Unexpected contract event")
1847+
}
1848+
count += 1
1849+
}
1850+
if count != 1 {
1851+
t.Fatal("Unexpected contract event number")
1852+
}
1853+
`,
1854+
nil,
1855+
nil,
1856+
nil,
1857+
nil,
1858+
},
17881859
}
17891860

17901861
// Tests that packages generated by the binder can be successfully compiled and

accounts/abi/unpack_test.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -762,20 +762,24 @@ func TestUnpackTuple(t *testing.T) {
762762
buff.Write(common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) // ret[b] = -1
763763

764764
// If the result is single tuple, use struct as return value container directly.
765-
v := struct {
765+
type v struct {
766766
A *big.Int
767767
B *big.Int
768-
}{new(big.Int), new(big.Int)}
768+
}
769+
type r struct {
770+
Result v
771+
}
772+
var ret0 = new(r)
773+
err = abi.UnpackIntoInterface(ret0, "tuple", buff.Bytes())
769774

770-
err = abi.UnpackIntoInterface(&v, "tuple", buff.Bytes())
771775
if err != nil {
772776
t.Error(err)
773777
} else {
774-
if v.A.Cmp(big.NewInt(1)) != 0 {
775-
t.Errorf("unexpected value unpacked: want %x, got %x", 1, v.A)
778+
if ret0.Result.A.Cmp(big.NewInt(1)) != 0 {
779+
t.Errorf("unexpected value unpacked: want %x, got %x", 1, ret0.Result.A)
776780
}
777-
if v.B.Cmp(big.NewInt(-1)) != 0 {
778-
t.Errorf("unexpected value unpacked: want %x, got %x", -1, v.B)
781+
if ret0.Result.B.Cmp(big.NewInt(-1)) != 0 {
782+
t.Errorf("unexpected value unpacked: want %x, got %x", -1, ret0.Result.B)
779783
}
780784
}
781785

0 commit comments

Comments
 (0)