Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
eb7ced13
Commit
eb7ced13
authored
Jul 31, 2020
by
harrylee
Committed by
33cn
Aug 06, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix a bug for test
parent
96cd55dd
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
462 additions
and
356 deletions
+462
-356
abi_test.go
plugin/dapp/evm/executor/abi/abi_test.go
+137
-137
type_test.go
plugin/dapp/evm/executor/abi/type_test.go
+9
-9
unpack.go
plugin/dapp/evm/executor/abi/unpack.go
+1
-1
unpack_test.go
plugin/dapp/evm/executor/abi/unpack_test.go
+306
-207
instructions.go
plugin/dapp/evm/executor/vm/runtime/instructions.go
+0
-1
jump_table.go
plugin/dapp/evm/executor/vm/runtime/jump_table.go
+9
-1
No files found.
plugin/dapp/evm/executor/abi/abi_test.go
View file @
eb7ced13
...
@@ -722,143 +722,143 @@ func TestBareEvents(t *testing.T) {
...
@@ -722,143 +722,143 @@ func TestBareEvents(t *testing.T) {
// }
// }
// When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
// When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
//func TestUnpackEvent(t *testing.T) {
func
TestUnpackEvent
(
t
*
testing
.
T
)
{
// const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
const
abiJSON
=
`[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
// abi, err := JSON(strings.NewReader(abiJSON))
abi
,
err
:=
JSON
(
strings
.
NewReader
(
abiJSON
))
// if err != nil {
if
err
!=
nil
{
// t.Fatal(err)
t
.
Fatal
(
err
)
// }
}
//
// const hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
// data, err := hex.DecodeString(hexdata)
// if err != nil {
// t.Fatal(err)
// }
// if len(data)%32 == 0 {
// t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
// }
//
// type ReceivedEvent struct {
// Sender common.Address
// Amount *big.Int
// Memo []byte
// }
// var ev ReceivedEvent
//
// err = abi.Unpack(&ev, "received", data)
// if err != nil {
// t.Error(err)
// }
//
// type ReceivedAddrEvent struct {
// Sender common.Address
// }
// var receivedAddrEv ReceivedAddrEvent
// err = abi.Unpack(&receivedAddrEv, "receivedAddr", data)
// if err != nil {
// t.Error(err)
// }
//}
//func TestUnpackEventIntoMap(t *testing.T) {
const
hexdata
=
`000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
// const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
data
,
err
:=
hex
.
DecodeString
(
hexdata
)
// abi, err := JSON(strings.NewReader(abiJSON))
if
err
!=
nil
{
// if err != nil {
t
.
Fatal
(
err
)
// t.Fatal(err)
}
// }
if
len
(
data
)
%
32
==
0
{
//
t
.
Errorf
(
"len(data) is %d, want a non-multiple of 32"
,
len
(
data
))
// const hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
}
// data, err := hex.DecodeString(hexdata)
// if err != nil {
type
ReceivedEvent
struct
{
// t.Fatal(err)
Sender
common
.
Address
// }
Amount
*
big
.
Int
// if len(data)%32 == 0 {
Memo
[]
byte
// t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
}
// }
var
ev
ReceivedEvent
//
// receivedMap := map[string]interface{}{}
err
=
abi
.
Unpack
(
&
ev
,
"received"
,
data
)
// expectedReceivedMap := map[string]interface{}{
if
err
!=
nil
{
// "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
t
.
Error
(
err
)
// "amount": big.NewInt(1),
}
// "memo": []byte{88},
// }
type
ReceivedAddrEvent
struct
{
// if err := abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
Sender
common
.
Address
// t.Error(err)
}
// }
var
receivedAddrEv
ReceivedAddrEvent
// if len(receivedMap) != 3 {
err
=
abi
.
Unpack
(
&
receivedAddrEv
,
"receivedAddr"
,
data
)
// t.Error("unpacked `received` map expected to have length 3")
if
err
!=
nil
{
// }
t
.
Error
(
err
)
// if receivedMap["sender"] != expectedReceivedMap["sender"] {
}
// t.Error("unpacked `received` map does not match expected map")
}
// }
// if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
func
TestUnpackEventIntoMap
(
t
*
testing
.
T
)
{
// t.Error("unpacked `received` map does not match expected map")
const
abiJSON
=
`[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
// }
abi
,
err
:=
JSON
(
strings
.
NewReader
(
abiJSON
))
// if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
if
err
!=
nil
{
// t.Error("unpacked `received` map does not match expected map")
t
.
Fatal
(
err
)
// }
}
//
// receivedAddrMap := map[string]interface{}{}
const
hexdata
=
`000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
// if err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data); err != nil {
data
,
err
:=
hex
.
DecodeString
(
hexdata
)
// t.Error(err)
if
err
!=
nil
{
// }
t
.
Fatal
(
err
)
// if len(receivedAddrMap) != 1 {
}
// t.Error("unpacked `receivedAddr` map expected to have length 1")
if
len
(
data
)
%
32
==
0
{
// }
t
.
Errorf
(
"len(data) is %d, want a non-multiple of 32"
,
len
(
data
))
// if receivedAddrMap["sender"] != expectedReceivedMap["sender"] {
}
// t.Error("unpacked `receivedAddr` map does not match expected map")
// }
receivedMap
:=
map
[
string
]
interface
{}{}
//}
expectedReceivedMap
:=
map
[
string
]
interface
{}{
//
"sender"
:
common
.
HexToAddress
(
"0x376c47978271565f56DEB45495afa69E59c16Ab2"
),
//func TestUnpackMethodIntoMap(t *testing.T) {
"amount"
:
big
.
NewInt
(
1
),
// const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]`
"memo"
:
[]
byte
{
88
},
// abi, err := JSON(strings.NewReader(abiJSON))
}
// if err != nil {
if
err
:=
abi
.
UnpackIntoMap
(
receivedMap
,
"received"
,
data
);
err
!=
nil
{
// t.Fatal(err)
t
.
Error
(
err
)
// }
}
// const hexdata = `00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001580000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158`
if
len
(
receivedMap
)
!=
3
{
// data, err := hex.DecodeString(hexdata)
t
.
Error
(
"unpacked `received` map expected to have length 3"
)
// if err != nil {
}
// t.Fatal(err)
if
receivedMap
[
"sender"
]
!=
expectedReceivedMap
[
"sender"
]
{
// }
t
.
Error
(
"unpacked `received` map does not match expected map"
)
// if len(data)%32 != 0 {
}
// t.Errorf("len(data) is %d, want a multiple of 32", len(data))
if
receivedMap
[
"amount"
]
.
(
*
big
.
Int
)
.
Cmp
(
expectedReceivedMap
[
"amount"
]
.
(
*
big
.
Int
))
!=
0
{
// }
t
.
Error
(
"unpacked `received` map does not match expected map"
)
//
}
// // Tests a method with no outputs
if
!
bytes
.
Equal
(
receivedMap
[
"memo"
]
.
([]
byte
),
expectedReceivedMap
[
"memo"
]
.
([]
byte
))
{
// receiveMap := map[string]interface{}{}
t
.
Error
(
"unpacked `received` map does not match expected map"
)
// if err = abi.UnpackIntoMap(receiveMap, "receive", data); err != nil {
}
// t.Error(err)
// }
receivedAddrMap
:=
map
[
string
]
interface
{}{}
// if len(receiveMap) > 0 {
if
err
=
abi
.
UnpackIntoMap
(
receivedAddrMap
,
"receivedAddr"
,
data
);
err
!=
nil
{
// t.Error("unpacked `receive` map expected to have length 0")
t
.
Error
(
err
)
// }
}
//
if
len
(
receivedAddrMap
)
!=
1
{
// // Tests a method with only outputs
t
.
Error
(
"unpacked `receivedAddr` map expected to have length 1"
)
// sendMap := map[string]interface{}{}
}
// if err = abi.UnpackIntoMap(sendMap, "send", data); err != nil {
if
receivedAddrMap
[
"sender"
]
!=
expectedReceivedMap
[
"sender"
]
{
// t.Error(err)
t
.
Error
(
"unpacked `receivedAddr` map does not match expected map"
)
// }
}
// if len(sendMap) != 1 {
}
// t.Error("unpacked `send` map expected to have length 1")
// }
func
TestUnpackMethodIntoMap
(
t
*
testing
.
T
)
{
// if sendMap["amount"].(*big.Int).Cmp(big.NewInt(1)) != 0 {
const
abiJSON
=
`[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]`
// t.Error("unpacked `send` map expected `amount` value of 1")
abi
,
err
:=
JSON
(
strings
.
NewReader
(
abiJSON
))
// }
if
err
!=
nil
{
//
t
.
Fatal
(
err
)
// // Tests a method with outputs and inputs
}
// getMap := map[string]interface{}{}
const
hexdata
=
`00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001580000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158`
// if err = abi.UnpackIntoMap(getMap, "get", data); err != nil {
data
,
err
:=
hex
.
DecodeString
(
hexdata
)
// t.Error(err)
if
err
!=
nil
{
// }
t
.
Fatal
(
err
)
// if len(getMap) != 1 {
}
// t.Error("unpacked `get` map expected to have length 1")
if
len
(
data
)
%
32
!=
0
{
// }
t
.
Errorf
(
"len(data) is %d, want a multiple of 32"
,
len
(
data
))
// expectedBytes := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0}
}
// if !bytes.Equal(getMap["hash"].([]byte), expectedBytes) {
// t.Errorf("unpacked `get` map expected `hash` value of %v", expectedBytes)
// Tests a method with no outputs
// }
receiveMap
:=
map
[
string
]
interface
{}{}
//}
if
err
=
abi
.
UnpackIntoMap
(
receiveMap
,
"receive"
,
data
);
err
!=
nil
{
t
.
Error
(
err
)
}
if
len
(
receiveMap
)
>
0
{
t
.
Error
(
"unpacked `receive` map expected to have length 0"
)
}
// Tests a method with only outputs
sendMap
:=
map
[
string
]
interface
{}{}
if
err
=
abi
.
UnpackIntoMap
(
sendMap
,
"send"
,
data
);
err
!=
nil
{
t
.
Error
(
err
)
}
if
len
(
sendMap
)
!=
1
{
t
.
Error
(
"unpacked `send` map expected to have length 1"
)
}
if
sendMap
[
"amount"
]
.
(
*
big
.
Int
)
.
Cmp
(
big
.
NewInt
(
1
))
!=
0
{
t
.
Error
(
"unpacked `send` map expected `amount` value of 1"
)
}
// Tests a method with outputs and inputs
getMap
:=
map
[
string
]
interface
{}{}
if
err
=
abi
.
UnpackIntoMap
(
getMap
,
"get"
,
data
);
err
!=
nil
{
t
.
Error
(
err
)
}
if
len
(
getMap
)
!=
1
{
t
.
Error
(
"unpacked `get` map expected to have length 1"
)
}
expectedBytes
:=
[]
byte
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
96
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
88
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
96
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
88
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
96
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
88
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
96
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
88
,
0
}
if
!
bytes
.
Equal
(
getMap
[
"hash"
]
.
([]
byte
),
expectedBytes
)
{
t
.
Errorf
(
"unpacked `get` map expected `hash` value of %v"
,
expectedBytes
)
}
}
func
TestUnpackIntoMapNamingConflict
(
t
*
testing
.
T
)
{
func
TestUnpackIntoMapNamingConflict
(
t
*
testing
.
T
)
{
// Two methods have the same name
// Two methods have the same name
...
@@ -886,6 +886,7 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) {
...
@@ -886,6 +886,7 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) {
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
hexdata
=
`000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
hexdata
=
`000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
data
,
err
=
hex
.
DecodeString
(
hexdata
)
data
,
err
=
hex
.
DecodeString
(
hexdata
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -898,7 +899,6 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) {
...
@@ -898,7 +899,6 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) {
if
err
=
abi
.
UnpackIntoMap
(
receivedMap
,
"received"
,
data
);
err
!=
nil
{
if
err
=
abi
.
UnpackIntoMap
(
receivedMap
,
"received"
,
data
);
err
!=
nil
{
t
.
Error
(
"naming conflict between two events; no error expected"
)
t
.
Error
(
"naming conflict between two events; no error expected"
)
}
}
// Method and event have the same name
// Method and event have the same name
abiJSON
=
`[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
abiJSON
=
`[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
abi
,
err
=
JSON
(
strings
.
NewReader
(
abiJSON
))
abi
,
err
=
JSON
(
strings
.
NewReader
(
abiJSON
))
...
...
plugin/dapp/evm/executor/abi/type_test.go
View file @
eb7ced13
...
@@ -21,10 +21,8 @@ import (
...
@@ -21,10 +21,8 @@ import (
"reflect"
"reflect"
"testing"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/holiman/uint256"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/davecgh/go-spew/spew"
)
)
// typeWithoutStringer is a alias for the Type type which simply doesn't implement
// typeWithoutStringer is a alias for the Type type which simply doesn't implement
...
@@ -213,10 +211,11 @@ func TestTypeCheck(t *testing.T) {
...
@@ -213,10 +211,11 @@ func TestTypeCheck(t *testing.T) {
{
"uint16[3]"
,
nil
,
[
4
]
uint16
{
1
,
2
,
3
},
"abi: cannot use [4]uint16 as type [3]uint16 as argument"
},
{
"uint16[3]"
,
nil
,
[
4
]
uint16
{
1
,
2
,
3
},
"abi: cannot use [4]uint16 as type [3]uint16 as argument"
},
{
"uint16[3]"
,
nil
,
[]
uint16
{
1
,
2
,
3
},
""
},
{
"uint16[3]"
,
nil
,
[]
uint16
{
1
,
2
,
3
},
""
},
{
"uint16[3]"
,
nil
,
[]
uint16
{
1
,
2
,
3
,
4
},
"abi: cannot use [4]uint16 as type [3]uint16 as argument"
},
{
"uint16[3]"
,
nil
,
[]
uint16
{
1
,
2
,
3
,
4
},
"abi: cannot use [4]uint16 as type [3]uint16 as argument"
},
{
"address[]"
,
nil
,
[]
common
.
Address
{
common
.
Uint256ToAddress
(
uint256
.
NewInt
()
.
SetUint64
(
1
))},
""
},
//转化为chain33中evm下Hash160Address 合约地址
{
"address[1]"
,
nil
,
[]
common
.
Address
{
common
.
Uint256ToAddress
(
uint256
.
NewInt
()
.
SetUint64
(
1
))},
""
},
{
"address[]"
,
nil
,
[]
common
.
Hash160Address
{{
1
}},
""
},
{
"address[1]"
,
nil
,
[
1
]
common
.
Address
{
common
.
Uint256ToAddress
(
uint256
.
NewInt
()
.
SetUint64
(
1
))},
""
},
{
"address[1]"
,
nil
,
[]
common
.
Hash160Address
{{
1
}},
""
},
{
"address[2]"
,
nil
,
[
1
]
common
.
Address
{
common
.
Uint256ToAddress
(
uint256
.
NewInt
()
.
SetUint64
(
1
))},
"abi: cannot use [1]array as type [2]array as argument"
},
{
"address[1]"
,
nil
,
[
1
]
common
.
Hash160Address
{{
1
}},
""
},
{
"address[2]"
,
nil
,
[
1
]
common
.
Hash160Address
{{
1
}},
"abi: cannot use [1]array as type [2]array as argument"
},
{
"bytes32"
,
nil
,
[
32
]
byte
{},
""
},
{
"bytes32"
,
nil
,
[
32
]
byte
{},
""
},
{
"bytes31"
,
nil
,
[
31
]
byte
{},
""
},
{
"bytes31"
,
nil
,
[
31
]
byte
{},
""
},
{
"bytes30"
,
nil
,
[
30
]
byte
{},
""
},
{
"bytes30"
,
nil
,
[
30
]
byte
{},
""
},
...
@@ -261,9 +260,10 @@ func TestTypeCheck(t *testing.T) {
...
@@ -261,9 +260,10 @@ func TestTypeCheck(t *testing.T) {
{
"string"
,
nil
,
[]
byte
{},
"abi: cannot use slice as type string as argument"
},
{
"string"
,
nil
,
[]
byte
{},
"abi: cannot use slice as type string as argument"
},
{
"bytes32[]"
,
nil
,
[][
32
]
byte
{{}},
""
},
{
"bytes32[]"
,
nil
,
[][
32
]
byte
{{}},
""
},
{
"function"
,
nil
,
[
24
]
byte
{},
""
},
{
"function"
,
nil
,
[
24
]
byte
{},
""
},
{
"bytes20"
,
nil
,
common
.
Address
{},
""
},
//转化为chain33中evm下Hash160Address 合约地址
{
"bytes20"
,
nil
,
common
.
Hash160Address
{},
""
},
{
"address"
,
nil
,
[
20
]
byte
{},
""
},
{
"address"
,
nil
,
[
20
]
byte
{},
""
},
{
"address"
,
nil
,
common
.
Address
{},
""
},
{
"address"
,
nil
,
common
.
Hash160
Address
{},
""
},
{
"bytes32[]]"
,
nil
,
""
,
"invalid arg type in abi"
},
{
"bytes32[]]"
,
nil
,
""
,
"invalid arg type in abi"
},
{
"invalidType"
,
nil
,
""
,
"unsupported arg type: invalidType"
},
{
"invalidType"
,
nil
,
""
,
"unsupported arg type: invalidType"
},
{
"invalidSlice[]"
,
nil
,
""
,
"unsupported arg type: invalidSlice"
},
{
"invalidSlice[]"
,
nil
,
""
,
"unsupported arg type: invalidSlice"
},
...
...
plugin/dapp/evm/executor/abi/unpack.go
View file @
eb7ced13
...
@@ -235,7 +235,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) {
...
@@ -235,7 +235,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) {
case
BoolTy
:
case
BoolTy
:
return
readBool
(
returnOutput
)
return
readBool
(
returnOutput
)
case
AddressTy
:
case
AddressTy
:
return
common
.
BytesToAddress
(
returnOutput
),
nil
return
common
.
BytesTo
Hash160
Address
(
returnOutput
),
nil
case
HashTy
:
case
HashTy
:
return
common
.
BytesToHash
(
returnOutput
),
nil
return
common
.
BytesToHash
(
returnOutput
),
nil
case
BytesTy
:
case
BytesTy
:
...
...
plugin/dapp/evm/executor/abi/unpack_test.go
View file @
eb7ced13
...
@@ -30,6 +30,34 @@ import (
...
@@ -30,6 +30,34 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
// TestUnpack tests the general pack/unpack tests in packing_test.go
func
TestUnpack
(
t
*
testing
.
T
)
{
for
i
,
test
:=
range
packUnpackTests
{
t
.
Run
(
strconv
.
Itoa
(
i
)
+
" "
+
test
.
def
,
func
(
t
*
testing
.
T
)
{
//Unpack
def
:=
fmt
.
Sprintf
(
`[{ "name" : "method", "type": "function", "outputs": %s}]`
,
test
.
def
)
abi
,
err
:=
JSON
(
strings
.
NewReader
(
def
))
if
err
!=
nil
{
t
.
Fatalf
(
"invalid ABI definition %s: %v"
,
def
,
err
)
}
encb
,
err
:=
hex
.
DecodeString
(
test
.
packed
)
if
err
!=
nil
{
t
.
Fatalf
(
"invalid hex %s: %v"
,
test
.
packed
,
err
)
}
outptr
:=
reflect
.
New
(
reflect
.
TypeOf
(
test
.
unpacked
))
err
=
abi
.
Unpack
(
outptr
.
Interface
(),
"method"
,
encb
)
if
err
!=
nil
{
t
.
Errorf
(
"test %d (%v) failed: %v"
,
i
,
test
.
def
,
err
)
return
}
out
:=
outptr
.
Elem
()
.
Interface
()
if
!
reflect
.
DeepEqual
(
test
.
unpacked
,
out
)
{
t
.
Errorf
(
"test %d (%v) failed: expected %v, got %v"
,
i
,
test
.
def
,
test
.
unpacked
,
out
)
}
})
}
}
type
unpackTest
struct
{
type
unpackTest
struct
{
def
string
// ABI definition JSON
def
string
// ABI definition JSON
enc
string
// evm return data
enc
string
// evm return data
...
@@ -51,16 +79,7 @@ func (test unpackTest) checkError(err error) error {
...
@@ -51,16 +79,7 @@ func (test unpackTest) checkError(err error) error {
}
}
var
unpackTests
=
[]
unpackTest
{
var
unpackTests
=
[]
unpackTest
{
{
// Bools
def
:
`[{ "type": "bool" }]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
want
:
true
,
},
{
def
:
`[{ "type": "bool" }]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000000"
,
want
:
false
,
},
{
{
def
:
`[{ "type": "bool" }]`
,
def
:
`[{ "type": "bool" }]`
,
enc
:
"0000000000000000000000000000000000000000000000000001000000000001"
,
enc
:
"0000000000000000000000000000000000000000000000000001000000000001"
,
...
@@ -73,11 +92,7 @@ var unpackTests = []unpackTest{
...
@@ -73,11 +92,7 @@ var unpackTests = []unpackTest{
want
:
false
,
want
:
false
,
err
:
"abi: improperly encoded boolean value"
,
err
:
"abi: improperly encoded boolean value"
,
},
},
{
// Integers
def
:
`[{"type": "uint32"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
want
:
uint32
(
1
),
},
{
{
def
:
`[{"type": "uint32"}]`
,
def
:
`[{"type": "uint32"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
...
@@ -91,16 +106,6 @@ var unpackTests = []unpackTest{
...
@@ -91,16 +106,6 @@ var unpackTests = []unpackTest{
err
:
"abi: cannot unmarshal *big.Int in to uint16"
,
err
:
"abi: cannot unmarshal *big.Int in to uint16"
,
},
},
{
{
def
:
`[{"type": "uint17"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
want
:
big
.
NewInt
(
1
),
},
{
def
:
`[{"type": "int32"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
want
:
int32
(
1
),
},
{
def
:
`[{"type": "int32"}]`
,
def
:
`[{"type": "int32"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
want
:
int16
(
0
),
want
:
int16
(
0
),
...
@@ -113,35 +118,9 @@ var unpackTests = []unpackTest{
...
@@ -113,35 +118,9 @@ var unpackTests = []unpackTest{
err
:
"abi: cannot unmarshal *big.Int in to int16"
,
err
:
"abi: cannot unmarshal *big.Int in to int16"
,
},
},
{
{
def
:
`[{"type": "int17"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001"
,
want
:
big
.
NewInt
(
1
),
},
{
def
:
`[{"type": "int256"}]`
,
enc
:
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
,
want
:
big
.
NewInt
(
-
1
),
},
{
def
:
`[{"type": "address"}]`
,
enc
:
"00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa300"
,
want
:
common
.
HexToAddress
(
"0x00Ce0d46d924CC8437c806721496599FC3FFA300"
)
.
ToAddress
()
.
String
(),
},
{
def
:
`[{"type": "bytes32"}]`
,
enc
:
"0100000000000000000000000000000000000000000000000000000000000000"
,
want
:
[
32
]
byte
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
},
{
def
:
`[{"type": "bytes"}]`
,
enc
:
"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000"
,
want
:
common
.
Hex2Bytes
(
"0100000000000000000000000000000000000000000000000000000000000000"
),
},
{
def
:
`[{"type": "bytes"}]`
,
def
:
`[{"type": "bytes"}]`
,
enc
:
"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000"
,
enc
:
"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000"
,
want
:
[
32
]
byte
{},
want
:
[
32
]
byte
{
1
},
err
:
"abi: cannot unmarshal []uint8 in to [32]uint8"
,
},
},
{
{
def
:
`[{"type": "bytes32"}]`
,
def
:
`[{"type": "bytes32"}]`
,
...
@@ -150,150 +129,21 @@ var unpackTests = []unpackTest{
...
@@ -150,150 +129,21 @@ var unpackTests = []unpackTest{
err
:
"abi: cannot unmarshal [32]uint8 in to []uint8"
,
err
:
"abi: cannot unmarshal [32]uint8 in to []uint8"
,
},
},
{
{
def
:
`[{"type": "bytes32"}]`
,
def
:
`[{"name":"___","type":"int256"}]`
,
enc
:
"0100000000000000000000000000000000000000000000000000000000000000"
,
want
:
[
32
]
byte
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
},
{
def
:
`[{"type": "function"}]`
,
enc
:
"0100000000000000000000000000000000000000000000000000000000000000"
,
want
:
[
24
]
byte
{
1
},
},
// slices
{
def
:
`[{"type": "uint8[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
uint8
{
1
,
2
},
},
{
def
:
`[{"type": "uint8[2]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
]
uint8
{
1
,
2
},
},
// multi dimensional, if these pass, all types that don't require length prefix should pass
{
def
:
`[{"type": "uint8[][]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000E0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[][]
uint8
{{
1
,
2
},
{
1
,
2
}},
},
{
def
:
`[{"type": "uint8[2][2]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
][
2
]
uint8
{{
1
,
2
},
{
1
,
2
}},
},
{
def
:
`[{"type": "uint8[][2]"}]`
,
enc
:
"000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001"
,
want
:
[
2
][]
uint8
{{
1
},
{
1
}},
},
{
def
:
`[{"type": "uint8[2][]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[][
2
]
uint8
{{
1
,
2
}},
},
{
def
:
`[{"type": "uint16[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
uint16
{
1
,
2
},
},
{
def
:
`[{"type": "uint16[2]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
]
uint16
{
1
,
2
},
},
{
def
:
`[{"type": "uint32[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
uint32
{
1
,
2
},
},
{
def
:
`[{"type": "uint32[2]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
]
uint32
{
1
,
2
},
},
{
def
:
`[{"type": "uint32[2][3][4]"}]`
,
enc
:
"000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000018"
,
want
:
[
4
][
3
][
2
]
uint32
{{{
1
,
2
},
{
3
,
4
},
{
5
,
6
}},
{{
7
,
8
},
{
9
,
10
},
{
11
,
12
}},
{{
13
,
14
},
{
15
,
16
},
{
17
,
18
}},
{{
19
,
20
},
{
21
,
22
},
{
23
,
24
}}},
},
{
def
:
`[{"type": "uint64[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
uint64
{
1
,
2
},
},
{
def
:
`[{"type": "uint64[2]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
]
uint64
{
1
,
2
},
},
{
def
:
`[{"type": "uint256[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
*
big
.
Int
{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
)},
},
{
def
:
`[{"type": "uint256[3]"}]`
,
enc
:
"000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"
,
want
:
[
3
]
*
big
.
Int
{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
),
big
.
NewInt
(
3
)},
},
{
def
:
`[{"type": "int8[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
int8
{
1
,
2
},
},
{
def
:
`[{"type": "int8[2]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
]
int8
{
1
,
2
},
},
{
def
:
`[{"type": "int16[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
int16
{
1
,
2
},
},
{
def
:
`[{"type": "int16[2]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
]
int16
{
1
,
2
},
},
{
def
:
`[{"type": "int32[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
int32
{
1
,
2
},
},
{
def
:
`[{"type": "int32[2]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
]
int32
{
1
,
2
},
want
:
struct
{
},
IntOne
*
big
.
Int
{
Intone
*
big
.
Int
def
:
`[{"type": "int64[]"}]`
,
}{
IntOne
:
big
.
NewInt
(
1
)},
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
int64
{
1
,
2
},
},
{
def
:
`[{"type": "int64[2]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[
2
]
int64
{
1
,
2
},
},
{
def
:
`[{"type": "int256[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
[]
*
big
.
Int
{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
)},
},
{
def
:
`[{"type": "int256[3]"}]`
,
enc
:
"000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"
,
want
:
[
3
]
*
big
.
Int
{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
),
big
.
NewInt
(
3
)},
},
},
// struct outputs
{
{
def
:
`[{"name":"int
1","type":"int256"},{"name":"int2
","type":"int256"}]`
,
def
:
`[{"name":"int
_one","type":"int256"},{"name":"IntOne
","type":"int256"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
struct
{
want
:
struct
{
Int1
*
big
.
Int
Int1
*
big
.
Int
Int2
*
big
.
Int
Int2
*
big
.
Int
}{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
)},
}{},
err
:
"abi: multiple outputs mapping to the same struct field 'IntOne'"
,
},
},
{
{
def
:
`[{"name":"int","type":"int256"},{"name":"Int","type":"int256"}]`
,
def
:
`[{"name":"int","type":"int256"},{"name":"Int","type":"int256"}]`
,
...
@@ -331,19 +181,44 @@ var unpackTests = []unpackTest{
...
@@ -331,19 +181,44 @@ var unpackTests = []unpackTest{
}{},
}{},
err
:
"abi: purely underscored output cannot unpack to struct"
,
err
:
"abi: purely underscored output cannot unpack to struct"
,
},
},
// Make sure only the first argument is consumed
{
def
:
`[{"name":"int_one","type":"int256"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
struct
{
IntOne
*
big
.
Int
}{
big
.
NewInt
(
1
)},
},
{
def
:
`[{"name":"int__one","type":"int256"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
struct
{
IntOne
*
big
.
Int
}{
big
.
NewInt
(
1
)},
},
{
def
:
`[{"name":"int_one_","type":"int256"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
want
:
struct
{
IntOne
*
big
.
Int
}{
big
.
NewInt
(
1
)},
},
}
}
func
TestUnpack
(
t
*
testing
.
T
)
{
// TestLocalUnpackTests runs test specially designed only for unpacking.
// All test cases that can be used to test packing and unpacking should move to packing_test.go
func
TestLocalUnpackTests
(
t
*
testing
.
T
)
{
for
i
,
test
:=
range
unpackTests
{
for
i
,
test
:=
range
unpackTests
{
t
.
Run
(
strconv
.
Itoa
(
i
),
func
(
t
*
testing
.
T
)
{
t
.
Run
(
strconv
.
Itoa
(
i
),
func
(
t
*
testing
.
T
)
{
def
:=
fmt
.
Sprintf
(
`[{ "name" : "method", "outputs": %s}]`
,
test
.
def
)
//Unpack
def
:=
fmt
.
Sprintf
(
`[{ "name" : "method", "type": "function", "outputs": %s}]`
,
test
.
def
)
abi
,
err
:=
JSON
(
strings
.
NewReader
(
def
))
abi
,
err
:=
JSON
(
strings
.
NewReader
(
def
))
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"invalid ABI definition %s: %v"
,
def
,
err
)
t
.
Fatalf
(
"invalid ABI definition %s: %v"
,
def
,
err
)
}
}
encb
,
err
:=
hex
.
DecodeString
(
test
.
enc
)
encb
,
err
:=
hex
.
DecodeString
(
test
.
enc
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"invalid hex
: %s"
+
test
.
enc
)
t
.
Fatalf
(
"invalid hex
%s: %v"
,
test
.
enc
,
err
)
}
}
outptr
:=
reflect
.
New
(
reflect
.
TypeOf
(
test
.
want
))
outptr
:=
reflect
.
New
(
reflect
.
TypeOf
(
test
.
want
))
err
=
abi
.
Unpack
(
outptr
.
Interface
(),
"method"
,
encb
)
err
=
abi
.
Unpack
(
outptr
.
Interface
(),
"method"
,
encb
)
...
@@ -359,6 +234,55 @@ func TestUnpack(t *testing.T) {
...
@@ -359,6 +234,55 @@ func TestUnpack(t *testing.T) {
}
}
}
}
func
TestUnpackSetDynamicArrayOutput
(
t
*
testing
.
T
)
{
abi
,
err
:=
JSON
(
strings
.
NewReader
(
`[{"constant":true,"inputs":[],"name":"testDynamicFixedBytes15","outputs":[{"name":"","type":"bytes15[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"testDynamicFixedBytes32","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"}]`
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
var
(
marshalledReturn32
=
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000230783132333435363738393000000000000000000000000000000000000000003078303938373635343332310000000000000000000000000000000000000000"
)
marshalledReturn15
=
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000230783031323334350000000000000000000000000000000000000000000000003078393837363534000000000000000000000000000000000000000000000000"
)
out32
[][
32
]
byte
out15
[][
15
]
byte
)
// test 32
err
=
abi
.
Unpack
(
&
out32
,
"testDynamicFixedBytes32"
,
marshalledReturn32
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
out32
)
!=
2
{
t
.
Fatalf
(
"expected array with 2 values, got %d"
,
len
(
out32
))
}
expected
:=
common
.
Hex2Bytes
(
"3078313233343536373839300000000000000000000000000000000000000000"
)
if
!
bytes
.
Equal
(
out32
[
0
][
:
],
expected
)
{
t
.
Errorf
(
"expected %x, got %x
\n
"
,
expected
,
out32
[
0
])
}
expected
=
common
.
Hex2Bytes
(
"3078303938373635343332310000000000000000000000000000000000000000"
)
if
!
bytes
.
Equal
(
out32
[
1
][
:
],
expected
)
{
t
.
Errorf
(
"expected %x, got %x
\n
"
,
expected
,
out32
[
1
])
}
// test 15
err
=
abi
.
Unpack
(
&
out15
,
"testDynamicFixedBytes32"
,
marshalledReturn15
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
out15
)
!=
2
{
t
.
Fatalf
(
"expected array with 2 values, got %d"
,
len
(
out15
))
}
expected
=
common
.
Hex2Bytes
(
"307830313233343500000000000000"
)
if
!
bytes
.
Equal
(
out15
[
0
][
:
],
expected
)
{
t
.
Errorf
(
"expected %x, got %x
\n
"
,
expected
,
out15
[
0
])
}
expected
=
common
.
Hex2Bytes
(
"307839383736353400000000000000"
)
if
!
bytes
.
Equal
(
out15
[
1
][
:
],
expected
)
{
t
.
Errorf
(
"expected %x, got %x
\n
"
,
expected
,
out15
[
1
])
}
}
type
methodMultiOutput
struct
{
type
methodMultiOutput
struct
{
Int
*
big
.
Int
Int
*
big
.
Int
String
string
String
string
...
@@ -366,7 +290,7 @@ type methodMultiOutput struct {
...
@@ -366,7 +290,7 @@ type methodMultiOutput struct {
func
methodMultiReturn
(
require
*
require
.
Assertions
)
(
ABI
,
[]
byte
,
methodMultiOutput
)
{
func
methodMultiReturn
(
require
*
require
.
Assertions
)
(
ABI
,
[]
byte
,
methodMultiOutput
)
{
const
definition
=
`[
const
definition
=
`[
{ "name" : "multi", "
constant" : false
, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
{ "name" : "multi", "
type": "function"
, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
var
expected
=
methodMultiOutput
{
big
.
NewInt
(
1
),
"hello"
}
var
expected
=
methodMultiOutput
{
big
.
NewInt
(
1
),
"hello"
}
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
...
@@ -386,6 +310,11 @@ func TestMethodMultiReturn(t *testing.T) {
...
@@ -386,6 +310,11 @@ func TestMethodMultiReturn(t *testing.T) {
Int
*
big
.
Int
Int
*
big
.
Int
}
}
newInterfaceSlice
:=
func
(
len
int
)
interface
{}
{
slice
:=
make
([]
interface
{},
len
)
return
&
slice
}
abi
,
data
,
expected
:=
methodMultiReturn
(
require
.
New
(
t
))
abi
,
data
,
expected
:=
methodMultiReturn
(
require
.
New
(
t
))
bigint
:=
new
(
big
.
Int
)
bigint
:=
new
(
big
.
Int
)
var
testCases
=
[]
struct
{
var
testCases
=
[]
struct
{
...
@@ -414,6 +343,16 @@ func TestMethodMultiReturn(t *testing.T) {
...
@@ -414,6 +343,16 @@ func TestMethodMultiReturn(t *testing.T) {
""
,
""
,
"Can unpack into an array"
,
"Can unpack into an array"
,
},
{
},
{
&
[
2
]
interface
{}{},
&
[
2
]
interface
{}{
expected
.
Int
,
expected
.
String
},
""
,
"Can unpack into interface array"
,
},
{
newInterfaceSlice
(
2
),
&
[]
interface
{}{
expected
.
Int
,
expected
.
String
},
""
,
"Can unpack into interface slice"
,
},
{
&
[]
interface
{}{
new
(
int
),
new
(
int
)},
&
[]
interface
{}{
new
(
int
),
new
(
int
)},
&
[]
interface
{}{
&
expected
.
Int
,
&
expected
.
String
},
&
[]
interface
{}{
&
expected
.
Int
,
&
expected
.
String
},
"abi: cannot unmarshal *big.Int in to int"
,
"abi: cannot unmarshal *big.Int in to int"
,
...
@@ -421,7 +360,7 @@ func TestMethodMultiReturn(t *testing.T) {
...
@@ -421,7 +360,7 @@ func TestMethodMultiReturn(t *testing.T) {
},
{
},
{
&
[]
interface
{}{
new
(
int
)},
&
[]
interface
{}{
new
(
int
)},
&
[]
interface
{}{},
&
[]
interface
{}{},
"abi: insufficient number of
elements in the list/array
for unpack, want 2, got 1"
,
"abi: insufficient number of
arguments
for unpack, want 2, got 1"
,
"Can not unpack into a slice with wrong types"
,
"Can not unpack into a slice with wrong types"
,
}}
}}
for
_
,
tc
:=
range
testCases
{
for
_
,
tc
:=
range
testCases
{
...
@@ -440,7 +379,7 @@ func TestMethodMultiReturn(t *testing.T) {
...
@@ -440,7 +379,7 @@ func TestMethodMultiReturn(t *testing.T) {
}
}
func
TestMultiReturnWithArray
(
t
*
testing
.
T
)
{
func
TestMultiReturnWithArray
(
t
*
testing
.
T
)
{
const
definition
=
`[{"name" : "multi", "outputs": [{"type": "uint64[3]"}, {"type": "uint64"}]}]`
const
definition
=
`[{"name" : "multi", "
type": "function", "
outputs": [{"type": "uint64[3]"}, {"type": "uint64"}]}]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
...
@@ -462,12 +401,74 @@ func TestMultiReturnWithArray(t *testing.T) {
...
@@ -462,12 +401,74 @@ func TestMultiReturnWithArray(t *testing.T) {
}
}
}
}
func
TestMultiReturnWithStringArray
(
t
*
testing
.
T
)
{
const
definition
=
`[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "uint256[3]"},{"name": "","type": "address"},{"name": "","type": "string[2]"},{"name": "","type": "bool"}]}]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
buff
:=
new
(
bytes
.
Buffer
)
buff
.
Write
(
common
.
Hex2Bytes
(
"000000000000000000000000000000000000000000000000000000005c1b78ea0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000001a055690d9db80000000000000000000000000000ab1257528b3782fb40d7ed5f72e624b744dffb2f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001048656c6c6f2c20457468657265756d2100000000000000000000000000000000"
))
temp
,
_
:=
big
.
NewInt
(
0
)
.
SetString
(
"30000000000000000000"
,
10
)
ret1
,
ret1Exp
:=
new
([
3
]
*
big
.
Int
),
[
3
]
*
big
.
Int
{
big
.
NewInt
(
1545304298
),
big
.
NewInt
(
6
),
temp
}
ret2
,
ret2Exp
:=
new
(
common
.
Hash160Address
),
common
.
HexToAddress
(
"ab1257528b3782fb40d7ed5f72e624b744dffb2f"
)
ret3
,
ret3Exp
:=
new
([
2
]
string
),
[
2
]
string
{
"Ethereum"
,
"Hello, Ethereum!"
}
ret4
,
ret4Exp
:=
new
(
bool
),
false
if
err
:=
abi
.
Unpack
(
&
[]
interface
{}{
ret1
,
ret2
,
ret3
,
ret4
},
"multi"
,
buff
.
Bytes
());
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
reflect
.
DeepEqual
(
*
ret1
,
ret1Exp
)
{
t
.
Error
(
"big.Int array result"
,
*
ret1
,
"!= Expected"
,
ret1Exp
)
}
if
!
reflect
.
DeepEqual
(
*
ret2
,
ret2Exp
)
{
t
.
Error
(
"address result"
,
*
ret2
,
"!= Expected"
,
ret2Exp
)
}
if
!
reflect
.
DeepEqual
(
*
ret3
,
ret3Exp
)
{
t
.
Error
(
"string array result"
,
*
ret3
,
"!= Expected"
,
ret3Exp
)
}
if
!
reflect
.
DeepEqual
(
*
ret4
,
ret4Exp
)
{
t
.
Error
(
"bool result"
,
*
ret4
,
"!= Expected"
,
ret4Exp
)
}
}
func
TestMultiReturnWithStringSlice
(
t
*
testing
.
T
)
{
const
definition
=
`[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "string[]"},{"name": "","type": "uint256[]"}]}]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
buff
:=
new
(
bytes
.
Buffer
)
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000040"
))
// output[0] offset
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000120"
))
// output[1] offset
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000002"
))
// output[0] length
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000040"
))
// output[0][0] offset
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000080"
))
// output[0][1] offset
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000008"
))
// output[0][0] length
buff
.
Write
(
common
.
Hex2Bytes
(
"657468657265756d000000000000000000000000000000000000000000000000"
))
// output[0][0] value
buff
.
Write
(
common
.
Hex2Bytes
(
"000000000000000000000000000000000000000000000000000000000000000b"
))
// output[0][1] length
buff
.
Write
(
common
.
Hex2Bytes
(
"676f2d657468657265756d000000000000000000000000000000000000000000"
))
// output[0][1] value
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000002"
))
// output[1] length
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000064"
))
// output[1][0] value
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000065"
))
// output[1][1] value
ret1
,
ret1Exp
:=
new
([]
string
),
[]
string
{
"ethereum"
,
"go-ethereum"
}
ret2
,
ret2Exp
:=
new
([]
*
big
.
Int
),
[]
*
big
.
Int
{
big
.
NewInt
(
100
),
big
.
NewInt
(
101
)}
if
err
:=
abi
.
Unpack
(
&
[]
interface
{}{
ret1
,
ret2
},
"multi"
,
buff
.
Bytes
());
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
reflect
.
DeepEqual
(
*
ret1
,
ret1Exp
)
{
t
.
Error
(
"string slice result"
,
*
ret1
,
"!= Expected"
,
ret1Exp
)
}
if
!
reflect
.
DeepEqual
(
*
ret2
,
ret2Exp
)
{
t
.
Error
(
"uint256 slice result"
,
*
ret2
,
"!= Expected"
,
ret2Exp
)
}
}
func
TestMultiReturnWithDeeplyNestedArray
(
t
*
testing
.
T
)
{
func
TestMultiReturnWithDeeplyNestedArray
(
t
*
testing
.
T
)
{
// Similar to TestMultiReturnWithArray, but with a special case in mind:
// Similar to TestMultiReturnWithArray, but with a special case in mind:
// values of nested static arrays count towards the size as well, and any element following
// values of nested static arrays count towards the size as well, and any element following
// after such nested array argument should be read with the correct offset,
// after such nested array argument should be read with the correct offset,
// so that it does not read content from the previous array argument.
// so that it does not read content from the previous array argument.
const
definition
=
`[{"name" : "multi", "outputs": [{"type": "uint64[3][2][4]"}, {"type": "uint64"}]}]`
const
definition
=
`[{"name" : "multi", "
type": "function", "
outputs": [{"type": "uint64[3][2][4]"}, {"type": "uint64"}]}]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
...
@@ -504,15 +505,15 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) {
...
@@ -504,15 +505,15 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) {
func
TestUnmarshal
(
t
*
testing
.
T
)
{
func
TestUnmarshal
(
t
*
testing
.
T
)
{
const
definition
=
`[
const
definition
=
`[
{ "name" : "int", "
constant" : false
, "outputs": [ { "type": "uint256" } ] },
{ "name" : "int", "
type": "function"
, "outputs": [ { "type": "uint256" } ] },
{ "name" : "bool", "
constant" : false
, "outputs": [ { "type": "bool" } ] },
{ "name" : "bool", "
type": "function"
, "outputs": [ { "type": "bool" } ] },
{ "name" : "bytes", "
constant" : false
, "outputs": [ { "type": "bytes" } ] },
{ "name" : "bytes", "
type": "function"
, "outputs": [ { "type": "bytes" } ] },
{ "name" : "fixed", "
constant" : false
, "outputs": [ { "type": "bytes32" } ] },
{ "name" : "fixed", "
type": "function"
, "outputs": [ { "type": "bytes32" } ] },
{ "name" : "multi", "
constant" : false
, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] },
{ "name" : "multi", "
type": "function"
, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] },
{ "name" : "intArraySingle", "
constant" : false
, "outputs": [ { "type": "uint256[3]" } ] },
{ "name" : "intArraySingle", "
type": "function"
, "outputs": [ { "type": "uint256[3]" } ] },
{ "name" : "addressSliceSingle", "
constant" : false
, "outputs": [ { "type": "address[]" } ] },
{ "name" : "addressSliceSingle", "
type": "function"
, "outputs": [ { "type": "address[]" } ] },
{ "name" : "addressSliceDouble", "
constant" : false
, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
{ "name" : "addressSliceDouble", "
type": "function"
, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
{ "name" : "mixedBytes", "
constant" : true
, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
{ "name" : "mixedBytes", "
type": "function", "stateMutability" : "view"
, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -688,7 +689,7 @@ func TestUnmarshal(t *testing.T) {
...
@@ -688,7 +689,7 @@ func TestUnmarshal(t *testing.T) {
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000020"
))
// offset
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000020"
))
// offset
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// size
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// size
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000100000000000000000000000000000000000000"
))
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000100000000000000000000000000000000000000"
))
//适配chain33中evm地址
var
outAddr
[]
common
.
Hash160Address
var
outAddr
[]
common
.
Hash160Address
err
=
abi
.
Unpack
(
&
outAddr
,
"addressSliceSingle"
,
buff
.
Bytes
())
err
=
abi
.
Unpack
(
&
outAddr
,
"addressSliceSingle"
,
buff
.
Bytes
())
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -751,6 +752,104 @@ func TestUnmarshal(t *testing.T) {
...
@@ -751,6 +752,104 @@ func TestUnmarshal(t *testing.T) {
}
}
}
}
func
TestUnpackTuple
(
t
*
testing
.
T
)
{
const
simpleTuple
=
`[{"name":"tuple","type":"function","outputs":[{"type":"tuple","name":"ret","components":[{"type":"int256","name":"a"},{"type":"int256","name":"b"}]}]}]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
simpleTuple
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
buff
:=
new
(
bytes
.
Buffer
)
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// ret[a] = 1
buff
.
Write
(
common
.
Hex2Bytes
(
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
))
// ret[b] = -1
// If the result is single tuple, use struct as return value container directly.
v
:=
struct
{
A
*
big
.
Int
B
*
big
.
Int
}{
new
(
big
.
Int
),
new
(
big
.
Int
)}
err
=
abi
.
Unpack
(
&
v
,
"tuple"
,
buff
.
Bytes
())
if
err
!=
nil
{
t
.
Error
(
err
)
}
else
{
if
v
.
A
.
Cmp
(
big
.
NewInt
(
1
))
!=
0
{
t
.
Errorf
(
"unexpected value unpacked: want %x, got %x"
,
1
,
v
.
A
)
}
if
v
.
B
.
Cmp
(
big
.
NewInt
(
-
1
))
!=
0
{
t
.
Errorf
(
"unexpected value unpacked: want %x, got %x"
,
-
1
,
v
.
B
)
}
}
// Test nested tuple
const
nestedTuple
=
`[{"name":"tuple","type":"function","outputs":[
{"type":"tuple","name":"s","components":[{"type":"uint256","name":"a"},{"type":"uint256[]","name":"b"},{"type":"tuple[]","name":"c","components":[{"name":"x", "type":"uint256"},{"name":"y","type":"uint256"}]}]},
{"type":"tuple","name":"t","components":[{"name":"x", "type":"uint256"},{"name":"y","type":"uint256"}]},
{"type":"uint256","name":"a"}
]}]`
abi
,
err
=
JSON
(
strings
.
NewReader
(
nestedTuple
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
buff
.
Reset
()
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000080"
))
// s offset
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000000"
))
// t.X = 0
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// t.Y = 1
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// a = 1
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// s.A = 1
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000060"
))
// s.B offset
buff
.
Write
(
common
.
Hex2Bytes
(
"00000000000000000000000000000000000000000000000000000000000000c0"
))
// s.C offset
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000002"
))
// s.B length
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// s.B[0] = 1
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000002"
))
// s.B[0] = 2
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000002"
))
// s.C length
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// s.C[0].X
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000002"
))
// s.C[0].Y
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000002"
))
// s.C[1].X
buff
.
Write
(
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))
// s.C[1].Y
type
T
struct
{
X
*
big
.
Int
`abi:"x"`
Z
*
big
.
Int
`abi:"y"`
// Test whether the abi tag works.
}
type
S
struct
{
A
*
big
.
Int
B
[]
*
big
.
Int
C
[]
T
}
type
Ret
struct
{
FieldS
S
`abi:"s"`
FieldT
T
`abi:"t"`
A
*
big
.
Int
}
var
ret
Ret
var
expected
=
Ret
{
FieldS
:
S
{
A
:
big
.
NewInt
(
1
),
B
:
[]
*
big
.
Int
{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
)},
C
:
[]
T
{
{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
)},
{
big
.
NewInt
(
2
),
big
.
NewInt
(
1
)},
},
},
FieldT
:
T
{
big
.
NewInt
(
0
),
big
.
NewInt
(
1
),
},
A
:
big
.
NewInt
(
1
),
}
err
=
abi
.
Unpack
(
&
ret
,
"tuple"
,
buff
.
Bytes
())
if
err
!=
nil
{
t
.
Error
(
err
)
}
if
reflect
.
DeepEqual
(
ret
,
expected
)
{
t
.
Error
(
"unexpected unpack value"
)
}
}
func
TestOOMMaliciousInput
(
t
*
testing
.
T
)
{
func
TestOOMMaliciousInput
(
t
*
testing
.
T
)
{
oomTests
:=
[]
unpackTest
{
oomTests
:=
[]
unpackTest
{
{
{
...
@@ -805,7 +904,7 @@ func TestOOMMaliciousInput(t *testing.T) {
...
@@ -805,7 +904,7 @@ func TestOOMMaliciousInput(t *testing.T) {
},
},
}
}
for
i
,
test
:=
range
oomTests
{
for
i
,
test
:=
range
oomTests
{
def
:=
fmt
.
Sprintf
(
`[{ "name" : "method", "outputs": %s}]`
,
test
.
def
)
def
:=
fmt
.
Sprintf
(
`[{ "name" : "method", "
type": "function", "
outputs": %s}]`
,
test
.
def
)
abi
,
err
:=
JSON
(
strings
.
NewReader
(
def
))
abi
,
err
:=
JSON
(
strings
.
NewReader
(
def
))
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"invalid ABI definition %s: %v"
,
def
,
err
)
t
.
Fatalf
(
"invalid ABI definition %s: %v"
,
def
,
err
)
...
...
plugin/dapp/evm/executor/vm/runtime/instructions.go
View file @
eb7ced13
...
@@ -458,7 +458,6 @@ func opBlockhash(pc *uint64, evm *EVM, callContext *callCtx) ([]byte, error) {
...
@@ -458,7 +458,6 @@ func opBlockhash(pc *uint64, evm *EVM, callContext *callCtx) ([]byte, error) {
// 获取区块打包者地址
// 获取区块打包者地址
func
opCoinbase
(
pc
*
uint64
,
evm
*
EVM
,
callContext
*
callCtx
)
([]
byte
,
error
)
{
func
opCoinbase
(
pc
*
uint64
,
evm
*
EVM
,
callContext
*
callCtx
)
([]
byte
,
error
)
{
// 需要注意coinbase可能为空的情况,这时将返回合约的创建者作为coinbase
// 需要注意coinbase可能为空的情况,这时将返回合约的创建者作为coinbase
callContext
.
stack
.
Push
(
new
(
uint256
.
Int
)
.
SetBytes
(
evm
.
Coinbase
.
Bytes
()))
if
evm
.
Coinbase
==
nil
{
if
evm
.
Coinbase
==
nil
{
callContext
.
stack
.
Push
(
new
(
uint256
.
Int
)
.
SetBytes
(
callContext
.
contract
.
CallerAddress
.
Bytes
()))
callContext
.
stack
.
Push
(
new
(
uint256
.
Int
)
.
SetBytes
(
callContext
.
contract
.
CallerAddress
.
Bytes
()))
}
else
{
}
else
{
...
...
plugin/dapp/evm/executor/vm/runtime/jump_table.go
View file @
eb7ced13
...
@@ -96,6 +96,14 @@ func NewYoloV1InstructionSet() JumpTable {
...
@@ -96,6 +96,14 @@ func NewYoloV1InstructionSet() JumpTable {
}
}
// create2 不支持
// create2 不支持
// chainID 不支持
// chainID 不支持
//PUSH1 指令变更
instructionSet
[
PUSH1
]
=
Operation
{
Execute
:
opPush1
,
GasCost
:
gas
.
Push
,
ValidateStack
:
mm
.
MakeStackFunc
(
0
,
1
),
Valid
:
true
,
}
return
instructionSet
return
instructionSet
}
}
...
@@ -519,7 +527,7 @@ func NewFrontierInstructionSet() [256]Operation {
...
@@ -519,7 +527,7 @@ func NewFrontierInstructionSet() [256]Operation {
Valid
:
true
,
Valid
:
true
,
},
},
PUSH1
:
{
PUSH1
:
{
Execute
:
opPush1
,
Execute
:
makePush
(
1
,
1
)
,
GasCost
:
gas
.
Push
,
GasCost
:
gas
.
Push
,
ValidateStack
:
mm
.
MakeStackFunc
(
0
,
1
),
ValidateStack
:
mm
.
MakeStackFunc
(
0
,
1
),
Valid
:
true
,
Valid
:
true
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment