Commit 781721f6 authored by Litian's avatar Litian

evm 支持abi代码逻辑基本完成

parent d33e674d
...@@ -294,7 +294,7 @@ func (rc *raftNode) updateValidator() { ...@@ -294,7 +294,7 @@ func (rc *raftNode) updateValidator() {
rlog.Debug(fmt.Sprintf("==============This is %s node!==============", status.RaftState.String())) rlog.Debug(fmt.Sprintf("==============This is %s node!==============", status.RaftState.String()))
continue continue
} else { } else {
// 获取到leader Id,选主成功 // 获取到leader ID,选主成功
if rc.id == int(status.Lead) { if rc.id == int(status.Lead) {
//leader选举出来之后即可添加addReadOnlyPeers //leader选举出来之后即可添加addReadOnlyPeers
if !flag && !isRestart { if !flag && !isRestart {
......
...@@ -236,7 +236,7 @@ func main() { ...@@ -236,7 +236,7 @@ func main() {
} }
////读取当前目录下的文件 ////读取当前目录下的文件
//dir_list, e := ioutil.ReadDir("D:/Repository/src/github.com/33cn/chain33/consensus/drivers/raft/tools/scripts") //dir_list, e := ioutil.ReadDir("ID:/Repository/src/github.com/33cn/chain33/consensus/drivers/raft/tools/scripts")
//if e != nil { //if e != nil {
// fmt.Println("read dir error") // fmt.Println("read dir error")
// return // return
......
...@@ -44,7 +44,7 @@ func JSON(reader io.Reader) (ABI, error) { ...@@ -44,7 +44,7 @@ func JSON(reader io.Reader) (ABI, error) {
return abi, nil return abi, nil
} }
// Pack the given method Name to conform the ABI. Method call's data // Pack the given method name to conform the ABI. Method call's data
// will consist of method_id, args0, arg1, ... argN. Method id consists // will consist of method_id, args0, arg1, ... argN. Method id consists
// of 4 bytes and arguments are all 32 bytes. // of 4 bytes and arguments are all 32 bytes.
// Method ids are created from the first 4 bytes of the hash of the // Method ids are created from the first 4 bytes of the hash of the
...@@ -70,7 +70,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { ...@@ -70,7 +70,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
return nil, err return nil, err
} }
// Pack up the method ID too if not a constructor and return // Pack up the method ID too if not a constructor and return
return append(method.Id(), arguments...), nil return append(method.ID(), arguments...), nil
} }
// Unpack output in v according to the abi specification // Unpack output in v according to the abi specification
...@@ -134,14 +134,14 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { ...@@ -134,14 +134,14 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
return nil return nil
} }
// MethodById looks up a method by the 4-byte id // MethodByID looks up a method by the 4-byte id
// returns nil if none found // returns nil if none found
func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { func (abi *ABI) MethodByID(sigdata []byte) (*Method, error) {
if len(sigdata) < 4 { if len(sigdata) < 4 {
return nil, fmt.Errorf("data too short (% bytes) for abi method lookup", len(sigdata)) return nil, fmt.Errorf("data too short (% bytes) for abi method lookup", len(sigdata))
} }
for _, method := range abi.Methods { for _, method := range abi.Methods {
if bytes.Equal(method.Id(), sigdata[:4]) { if bytes.Equal(method.ID(), sigdata[:4]) {
return &method, nil return &method, nil
} }
} }
......
...@@ -33,26 +33,26 @@ import ( ...@@ -33,26 +33,26 @@ import (
const jsondata = ` const jsondata = `
[ [
{ "type" : "function", "Name" : "balance", "constant" : true }, { "type" : "function", "name" : "balance", "constant" : true },
{ "type" : "function", "Name" : "send", "constant" : false, "inputs" : [ { "Name" : "amount", "type" : "uint256" } ] } { "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
]` ]`
const jsondata2 = ` const jsondata2 = `
[ [
{ "type" : "function", "Name" : "balance", "constant" : true }, { "type" : "function", "name" : "balance", "constant" : true },
{ "type" : "function", "Name" : "send", "constant" : false, "inputs" : [ { "Name" : "amount", "type" : "uint256" } ] }, { "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] },
{ "type" : "function", "Name" : "test", "constant" : false, "inputs" : [ { "Name" : "number", "type" : "uint32" } ] }, { "type" : "function", "name" : "test", "constant" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] },
{ "type" : "function", "Name" : "string", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "string" } ] }, { "type" : "function", "name" : "string", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] },
{ "type" : "function", "Name" : "bool", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "bool" } ] }, { "type" : "function", "name" : "bool", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] },
{ "type" : "function", "Name" : "address", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "address" } ] }, { "type" : "function", "name" : "address", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "address" } ] },
{ "type" : "function", "Name" : "uint64[2]", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "uint64[2]" } ] }, { "type" : "function", "name" : "uint64[2]", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] },
{ "type" : "function", "Name" : "uint64[]", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "uint64[]" } ] }, { "type" : "function", "name" : "uint64[]", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] },
{ "type" : "function", "Name" : "foo", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "uint32" } ] }, { "type" : "function", "name" : "foo", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] },
{ "type" : "function", "Name" : "bar", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "uint32" }, { "Name" : "string", "type" : "uint16" } ] }, { "type" : "function", "name" : "bar", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] },
{ "type" : "function", "Name" : "slice", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "uint32[2]" } ] }, { "type" : "function", "name" : "slice", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] },
{ "type" : "function", "Name" : "slice256", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "uint256[2]" } ] }, { "type" : "function", "name" : "slice256", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] },
{ "type" : "function", "Name" : "sliceAddress", "constant" : false, "inputs" : [ { "Name" : "inputs", "type" : "address[]" } ] }, { "type" : "function", "name" : "sliceAddress", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "address[]" } ] },
{ "type" : "function", "Name" : "sliceMultiAddress", "constant" : false, "inputs" : [ { "Name" : "a", "type" : "address[]" }, { "Name" : "b", "type" : "address[]" } ] } { "type" : "function", "name" : "sliceMultiAddress", "constant" : false, "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] }
]` ]`
func TestReader(t *testing.T) { func TestReader(t *testing.T) {
...@@ -185,8 +185,8 @@ func TestMethodSignature(t *testing.T) { ...@@ -185,8 +185,8 @@ func TestMethodSignature(t *testing.T) {
} }
idexp := crypto.Keccak256([]byte(exp))[:4] idexp := crypto.Keccak256([]byte(exp))[:4]
if !bytes.Equal(m.Id(), idexp) { if !bytes.Equal(m.ID(), idexp) {
t.Errorf("expected ids to match %x != %x", m.Id(), idexp) t.Errorf("expected ids to match %x != %x", m.ID(), idexp)
} }
uintt, _ := NewType("uint256") uintt, _ := NewType("uint256")
...@@ -221,7 +221,7 @@ func TestMultiPack(t *testing.T) { ...@@ -221,7 +221,7 @@ func TestMultiPack(t *testing.T) {
} }
func ExampleJSON() { func ExampleJSON() {
const definition = `[{"constant":true,"inputs":[{"Name":"","type":"address"}],"Name":"isBar","outputs":[{"Name":"","type":"bool"}],"type":"function"}]` const definition = `[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isBar","outputs":[{"name":"","type":"bool"}],"type":"function"}]`
abi, err := JSON(strings.NewReader(definition)) abi, err := JSON(strings.NewReader(definition))
if err != nil { if err != nil {
...@@ -239,9 +239,9 @@ func ExampleJSON() { ...@@ -239,9 +239,9 @@ func ExampleJSON() {
func TestInputVariableInputLength(t *testing.T) { func TestInputVariableInputLength(t *testing.T) {
const definition = `[ const definition = `[
{ "type" : "function", "Name" : "strOne", "constant" : true, "inputs" : [ { "Name" : "str", "type" : "string" } ] }, { "type" : "function", "name" : "strOne", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" } ] },
{ "type" : "function", "Name" : "bytesOne", "constant" : true, "inputs" : [ { "Name" : "str", "type" : "bytes" } ] }, { "type" : "function", "name" : "bytesOne", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" } ] },
{ "type" : "function", "Name" : "strTwo", "constant" : true, "inputs" : [ { "Name" : "str", "type" : "string" }, { "Name" : "str1", "type" : "string" } ] } { "type" : "function", "name" : "strTwo", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "str1", "type" : "string" } ] }
]` ]`
abi, err := JSON(strings.NewReader(definition)) abi, err := JSON(strings.NewReader(definition))
...@@ -367,11 +367,11 @@ func TestInputVariableInputLength(t *testing.T) { ...@@ -367,11 +367,11 @@ func TestInputVariableInputLength(t *testing.T) {
func TestInputFixedArrayAndVariableInputLength(t *testing.T) { func TestInputFixedArrayAndVariableInputLength(t *testing.T) {
const definition = `[ const definition = `[
{ "type" : "function", "Name" : "fixedArrStr", "constant" : true, "inputs" : [ { "Name" : "str", "type" : "string" }, { "Name" : "fixedArr", "type" : "uint256[2]" } ] }, { "type" : "function", "name" : "fixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] },
{ "type" : "function", "Name" : "fixedArrBytes", "constant" : true, "inputs" : [ { "Name" : "str", "type" : "bytes" }, { "Name" : "fixedArr", "type" : "uint256[2]" } ] }, { "type" : "function", "name" : "fixedArrBytes", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] },
{ "type" : "function", "Name" : "mixedArrStr", "constant" : true, "inputs" : [ { "Name" : "str", "type" : "string" }, { "Name" : "fixedArr", "type": "uint256[2]" }, { "Name" : "dynArr", "type": "uint256[]" } ] }, { "type" : "function", "name" : "mixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type": "uint256[2]" }, { "name" : "dynArr", "type": "uint256[]" } ] },
{ "type" : "function", "Name" : "doubleFixedArrStr", "constant" : true, "inputs" : [ { "Name" : "str", "type" : "string" }, { "Name" : "fixedArr1", "type": "uint256[2]" }, { "Name" : "fixedArr2", "type": "uint256[3]" } ] }, { "type" : "function", "name" : "doubleFixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type": "uint256[2]" }, { "name" : "fixedArr2", "type": "uint256[3]" } ] },
{ "type" : "function", "Name" : "multipleMixedArrStr", "constant" : true, "inputs" : [ { "Name" : "str", "type" : "string" }, { "Name" : "fixedArr1", "type": "uint256[2]" }, { "Name" : "dynArr", "type" : "uint256[]" }, { "Name" : "fixedArr2", "type" : "uint256[3]" } ] } { "type" : "function", "name" : "multipleMixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type": "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] }
]` ]`
abi, err := JSON(strings.NewReader(definition)) abi, err := JSON(strings.NewReader(definition))
...@@ -548,7 +548,7 @@ func TestInputFixedArrayAndVariableInputLength(t *testing.T) { ...@@ -548,7 +548,7 @@ func TestInputFixedArrayAndVariableInputLength(t *testing.T) {
} }
func TestDefaultFunctionParsing(t *testing.T) { func TestDefaultFunctionParsing(t *testing.T) {
const definition = `[{ "Name" : "balance" }]` const definition = `[{ "name" : "balance" }]`
abi, err := JSON(strings.NewReader(definition)) abi, err := JSON(strings.NewReader(definition))
if err != nil { if err != nil {
...@@ -562,9 +562,9 @@ func TestDefaultFunctionParsing(t *testing.T) { ...@@ -562,9 +562,9 @@ func TestDefaultFunctionParsing(t *testing.T) {
func TestBareEvents(t *testing.T) { func TestBareEvents(t *testing.T) {
const definition = `[ const definition = `[
{ "type" : "event", "Name" : "balance" }, { "type" : "event", "name" : "balance" },
{ "type" : "event", "Name" : "anon", "anonymous" : true}, { "type" : "event", "name" : "anon", "anonymous" : true},
{ "type" : "event", "Name" : "args", "inputs" : [{ "indexed":false, "Name":"arg0", "type":"uint256" }, { "indexed":true, "Name":"arg1", "type":"address" }] } { "type" : "event", "name" : "args", "inputs" : [{ "indexed":false, "name":"arg0", "type":"uint256" }, { "indexed":true, "name":"arg1", "type":"address" }] }
]` ]`
arg0, _ := NewType("uint256") arg0, _ := NewType("uint256")
...@@ -606,7 +606,7 @@ func TestBareEvents(t *testing.T) { ...@@ -606,7 +606,7 @@ func TestBareEvents(t *testing.T) {
} }
for i, arg := range exp.Args { for i, arg := range exp.Args {
if arg.Name != got.Inputs[i].Name { if arg.Name != got.Inputs[i].Name {
t.Errorf("events[%s].Input[%d] has an invalid Name, want %s, got %s", name, i, arg.Name, got.Inputs[i].Name) t.Errorf("events[%s].Input[%d] has an invalid name, want %s, got %s", name, i, arg.Name, got.Inputs[i].Name)
} }
if arg.Indexed != got.Inputs[i].Indexed { if arg.Indexed != got.Inputs[i].Indexed {
t.Errorf("events[%s].Input[%d] has an invalid indexed indication, want %v, got %v", name, i, arg.Indexed, got.Inputs[i].Indexed) t.Errorf("events[%s].Input[%d] has an invalid indexed indication, want %v, got %v", name, i, arg.Indexed, got.Inputs[i].Indexed)
...@@ -623,14 +623,14 @@ func TestBareEvents(t *testing.T) { ...@@ -623,14 +623,14 @@ func TestBareEvents(t *testing.T) {
// event received(address sender, uint amount, bytes memo); // event received(address sender, uint amount, bytes memo);
// event receivedAddr(address sender); // event receivedAddr(address sender);
// function receive(bytes memo) external payable { // function receive(bytes memo) external payable {
// received(msg.sender, msg.Value, memo); // received(msg.sender, msg.value, memo);
// receivedAddr(msg.sender); // receivedAddr(msg.sender);
// } // }
// } // }
// 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)
...@@ -646,7 +646,7 @@ func TestUnpackEvent(t *testing.T) { ...@@ -646,7 +646,7 @@ func TestUnpackEvent(t *testing.T) {
} }
type ReceivedEvent struct { type ReceivedEvent struct {
Address common.Hash160Address Address common.Hash160Address
Amount *big.Int Amount *big.Int
Memo []byte Memo []byte
} }
...@@ -660,7 +660,7 @@ func TestUnpackEvent(t *testing.T) { ...@@ -660,7 +660,7 @@ func TestUnpackEvent(t *testing.T) {
} }
type ReceivedAddrEvent struct { type ReceivedAddrEvent struct {
Address common.Hash160Address Address common.Hash160Address
} }
var receivedAddrEv ReceivedAddrEvent var receivedAddrEv ReceivedAddrEvent
err = abi.Unpack(&receivedAddrEv, "receivedAddr", data) err = abi.Unpack(&receivedAddrEv, "receivedAddr", data)
...@@ -673,27 +673,27 @@ func TestUnpackEvent(t *testing.T) { ...@@ -673,27 +673,27 @@ func TestUnpackEvent(t *testing.T) {
func TestABI_MethodById(t *testing.T) { func TestABI_MethodById(t *testing.T) {
const abiJSON = `[ const abiJSON = `[
{"type":"function","Name":"receive","constant":false,"inputs":[{"Name":"memo","type":"bytes"}],"outputs":[],"payable":true,"stateMutability":"payable"}, {"type":"function","name":"receive","constant":false,"inputs":[{"name":"memo","type":"bytes"}],"outputs":[],"payable":true,"stateMutability":"payable"},
{"type":"event","Name":"received","anonymous":false,"inputs":[{"indexed":false,"Name":"sender","type":"address"},{"indexed":false,"Name":"amount","type":"uint256"},{"indexed":false,"Name":"memo","type":"bytes"}]}, {"type":"event","name":"received","anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}]},
{"type":"function","Name":"fixedArrStr","constant":true,"inputs":[{"Name":"str","type":"string"},{"Name":"fixedArr","type":"uint256[2]"}]}, {"type":"function","name":"fixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr","type":"uint256[2]"}]},
{"type":"function","Name":"fixedArrBytes","constant":true,"inputs":[{"Name":"str","type":"bytes"},{"Name":"fixedArr","type":"uint256[2]"}]}, {"type":"function","name":"fixedArrBytes","constant":true,"inputs":[{"name":"str","type":"bytes"},{"name":"fixedArr","type":"uint256[2]"}]},
{"type":"function","Name":"mixedArrStr","constant":true,"inputs":[{"Name":"str","type":"string"},{"Name":"fixedArr","type":"uint256[2]"},{"Name":"dynArr","type":"uint256[]"}]}, {"type":"function","name":"mixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr","type":"uint256[2]"},{"name":"dynArr","type":"uint256[]"}]},
{"type":"function","Name":"doubleFixedArrStr","constant":true,"inputs":[{"Name":"str","type":"string"},{"Name":"fixedArr1","type":"uint256[2]"},{"Name":"fixedArr2","type":"uint256[3]"}]}, {"type":"function","name":"doubleFixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr1","type":"uint256[2]"},{"name":"fixedArr2","type":"uint256[3]"}]},
{"type":"function","Name":"multipleMixedArrStr","constant":true,"inputs":[{"Name":"str","type":"string"},{"Name":"fixedArr1","type":"uint256[2]"},{"Name":"dynArr","type":"uint256[]"},{"Name":"fixedArr2","type":"uint256[3]"}]}, {"type":"function","name":"multipleMixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr1","type":"uint256[2]"},{"name":"dynArr","type":"uint256[]"},{"name":"fixedArr2","type":"uint256[3]"}]},
{"type":"function","Name":"balance","constant":true}, {"type":"function","name":"balance","constant":true},
{"type":"function","Name":"send","constant":false,"inputs":[{"Name":"amount","type":"uint256"}]}, {"type":"function","name":"send","constant":false,"inputs":[{"name":"amount","type":"uint256"}]},
{"type":"function","Name":"test","constant":false,"inputs":[{"Name":"number","type":"uint32"}]}, {"type":"function","name":"test","constant":false,"inputs":[{"name":"number","type":"uint32"}]},
{"type":"function","Name":"string","constant":false,"inputs":[{"Name":"inputs","type":"string"}]}, {"type":"function","name":"string","constant":false,"inputs":[{"name":"inputs","type":"string"}]},
{"type":"function","Name":"bool","constant":false,"inputs":[{"Name":"inputs","type":"bool"}]}, {"type":"function","name":"bool","constant":false,"inputs":[{"name":"inputs","type":"bool"}]},
{"type":"function","Name":"address","constant":false,"inputs":[{"Name":"inputs","type":"address"}]}, {"type":"function","name":"address","constant":false,"inputs":[{"name":"inputs","type":"address"}]},
{"type":"function","Name":"uint64[2]","constant":false,"inputs":[{"Name":"inputs","type":"uint64[2]"}]}, {"type":"function","name":"uint64[2]","constant":false,"inputs":[{"name":"inputs","type":"uint64[2]"}]},
{"type":"function","Name":"uint64[]","constant":false,"inputs":[{"Name":"inputs","type":"uint64[]"}]}, {"type":"function","name":"uint64[]","constant":false,"inputs":[{"name":"inputs","type":"uint64[]"}]},
{"type":"function","Name":"foo","constant":false,"inputs":[{"Name":"inputs","type":"uint32"}]}, {"type":"function","name":"foo","constant":false,"inputs":[{"name":"inputs","type":"uint32"}]},
{"type":"function","Name":"bar","constant":false,"inputs":[{"Name":"inputs","type":"uint32"},{"Name":"string","type":"uint16"}]}, {"type":"function","name":"bar","constant":false,"inputs":[{"name":"inputs","type":"uint32"},{"name":"string","type":"uint16"}]},
{"type":"function","Name":"_slice","constant":false,"inputs":[{"Name":"inputs","type":"uint32[2]"}]}, {"type":"function","name":"_slice","constant":false,"inputs":[{"name":"inputs","type":"uint32[2]"}]},
{"type":"function","Name":"__slice256","constant":false,"inputs":[{"Name":"inputs","type":"uint256[2]"}]}, {"type":"function","name":"__slice256","constant":false,"inputs":[{"name":"inputs","type":"uint256[2]"}]},
{"type":"function","Name":"sliceAddress","constant":false,"inputs":[{"Name":"inputs","type":"address[]"}]}, {"type":"function","name":"sliceAddress","constant":false,"inputs":[{"name":"inputs","type":"address[]"}]},
{"type":"function","Name":"sliceMultiAddress","constant":false,"inputs":[{"Name":"a","type":"address[]"},{"Name":"b","type":"address[]"}]} {"type":"function","name":"sliceMultiAddress","constant":false,"inputs":[{"name":"a","type":"address[]"},{"name":"b","type":"address[]"}]}
] ]
` `
abi, err := JSON(strings.NewReader(abiJSON)) abi, err := JSON(strings.NewReader(abiJSON))
...@@ -702,23 +702,23 @@ func TestABI_MethodById(t *testing.T) { ...@@ -702,23 +702,23 @@ func TestABI_MethodById(t *testing.T) {
} }
for name, m := range abi.Methods { for name, m := range abi.Methods {
a := fmt.Sprintf("%v", m) a := fmt.Sprintf("%v", m)
m2, err := abi.MethodById(m.Id()) m2, err := abi.MethodByID(m.ID())
if err != nil { if err != nil {
t.Fatalf("Failed to look up ABI method: %v", err) t.Fatalf("Failed to look up ABI method: %v", err)
} }
b := fmt.Sprintf("%v", m2) b := fmt.Sprintf("%v", m2)
if a != b { if a != b {
t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, common.Bytes2Hex(m.Id())) t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, common.Bytes2Hex(m.ID()))
} }
} }
// Also test empty // Also test empty
if _, err := abi.MethodById([]byte{0x00}); err == nil { if _, err := abi.MethodByID([]byte{0x00}); err == nil {
t.Errorf("Expected error, too short to decode data") t.Errorf("Expected error, too short to decode data")
} }
if _, err := abi.MethodById([]byte{}); err == nil { if _, err := abi.MethodByID([]byte{}); err == nil {
t.Errorf("Expected error, too short to decode data") t.Errorf("Expected error, too short to decode data")
} }
if _, err := abi.MethodById(nil); err == nil { if _, err := abi.MethodByID(nil); err == nil {
t.Errorf("Expected error, nil is short to decode data") t.Errorf("Expected error, nil is short to decode data")
} }
} }
...@@ -3,19 +3,22 @@ package abi ...@@ -3,19 +3,22 @@ package abi
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/golang-collections/collections/stack"
"math/big" "math/big"
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/golang-collections/collections/stack"
"github.com/kataras/iris/core/errors"
) )
// Pack 使用ABI方式调用时,将调用方式转换为EVM底层处理的十六进制编码 // Pack 使用ABI方式调用时,将调用方式转换为EVM底层处理的十六进制编码
// abiData 完整的ABI定义 // abiData 完整的ABI定义
// param 调用方法及参数 // param 调用方法及参数
// readOnly 是否只读,如果调用的方法不为只读,则报错
// 调用方式: foo(param1,param2) // 调用方式: foo(param1,param2)
func Pack(param, abiData string) (methodName string, packData []byte, err error) { func Pack(param, abiData string, readOnly bool) (methodName string, packData []byte, err error) {
// 首先解析参数字符串,分析出方法名以及个参数取值 // 首先解析参数字符串,分析出方法名以及个参数取值
methodName, params, err := procFuncCall(param) methodName, params, err := procFuncCall(param)
if err != nil { if err != nil {
...@@ -35,6 +38,13 @@ func Pack(param, abiData string) (methodName string, packData []byte, err error) ...@@ -35,6 +38,13 @@ func Pack(param, abiData string) (methodName string, packData []byte, err error)
return methodName, packData, err return methodName, packData, err
} }
if readOnly && !method.Const {
return methodName, packData, errors.New("method is not readonly")
}
if len(params) != method.Inputs.LengthNonIndexed() {
err = fmt.Errorf("function params error:%v", params)
return methodName, packData, err
}
// 获取方法参数对象,遍历解析各参数,获得参数的Go取值 // 获取方法参数对象,遍历解析各参数,获得参数的Go取值
paramVals := []interface{}{} paramVals := []interface{}{}
if len(params) != 0 { if len(params) != 0 {
...@@ -62,7 +72,9 @@ func Pack(param, abiData string) (methodName string, packData []byte, err error) ...@@ -62,7 +72,9 @@ func Pack(param, abiData string) (methodName string, packData []byte, err error)
// data 合约方法返回值 // data 合约方法返回值
// abiData 完整的ABI定义 // abiData 完整的ABI定义
func Unpack(data []byte, methodName, abiData string) (output string, err error) { func Unpack(data []byte, methodName, abiData string) (output string, err error) {
if len(data) == 0 {
return output, err
}
// 解析ABI数据结构,获取本次调用的方法对象 // 解析ABI数据结构,获取本次调用的方法对象
abi, err := JSON(strings.NewReader(abiData)) abi, err := JSON(strings.NewReader(abiData))
if err != nil { if err != nil {
...@@ -75,6 +87,10 @@ func Unpack(data []byte, methodName, abiData string) (output string, err error) ...@@ -75,6 +87,10 @@ func Unpack(data []byte, methodName, abiData string) (output string, err error)
return output, fmt.Errorf("function %v not exists", methodName) return output, fmt.Errorf("function %v not exists", methodName)
} }
if method.Outputs.LengthNonIndexed() == 0 {
return output, err
}
values, err := method.Outputs.UnpackValues(data) values, err := method.Outputs.UnpackValues(data)
if err != nil { if err != nil {
return output, err return output, err
...@@ -95,9 +111,13 @@ func Unpack(data []byte, methodName, abiData string) (output string, err error) ...@@ -95,9 +111,13 @@ func Unpack(data []byte, methodName, abiData string) (output string, err error)
return string(jsondata), err return string(jsondata), err
} }
// Param 返回值参数结构定义
type Param struct { type Param struct {
Name string `json:"name"` // Name 参数名称
Type string `json:"type"` Name string `json:"name"`
// Type 参数类型
Type string `json:"type"`
// Value 参数取值
Value interface{} `json:"value"` Value interface{} `json:"value"`
} }
...@@ -143,11 +163,10 @@ func str2GoValue(typ Type, val string) (res interface{}, err error) { ...@@ -143,11 +163,10 @@ func str2GoValue(typ Type, val string) (res interface{}, err error) {
return res, err return res, err
} }
return convertInt(x, typ.Kind), nil return convertInt(x, typ.Kind), nil
} else {
b := new(big.Int)
b.SetString(val, 10)
return b, err
} }
b := new(big.Int)
b.SetString(val, 10)
return b, err
case UintTy: case UintTy:
if typ.Size < 256 { if typ.Size < 256 {
x, err := strconv.ParseUint(val, 10, typ.Size) x, err := strconv.ParseUint(val, 10, typ.Size)
...@@ -155,11 +174,10 @@ func str2GoValue(typ Type, val string) (res interface{}, err error) { ...@@ -155,11 +174,10 @@ func str2GoValue(typ Type, val string) (res interface{}, err error) {
return res, err return res, err
} }
return convertUint(x, typ.Kind), nil return convertUint(x, typ.Kind), nil
} else {
b := new(big.Int)
b.SetString(val, 10)
return b, err
} }
b := new(big.Int)
b.SetString(val, 10)
return b, err
case BoolTy: case BoolTy:
x, err := strconv.ParseBool(val) x, err := strconv.ParseBool(val)
if err != nil { if err != nil {
...@@ -230,7 +248,6 @@ func str2GoValue(typ Type, val string) (res interface{}, err error) { ...@@ -230,7 +248,6 @@ func str2GoValue(typ Type, val string) (res interface{}, err error) {
default: default:
return res, fmt.Errorf("not support type: %v", typ.stringKind) return res, fmt.Errorf("not support type: %v", typ.stringKind)
} }
return res, nil
} }
// 本方法可以将一个表示数组的字符串,经过处理后,返回数组内的字面元素; // 本方法可以将一个表示数组的字符串,经过处理后,返回数组内的字面元素;
......
...@@ -3,10 +3,11 @@ package abi ...@@ -3,10 +3,11 @@ package abi
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/stretchr/testify/assert"
"reflect" "reflect"
"testing" "testing"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/stretchr/testify/assert"
) )
func TestABI_Pack(t *testing.T) { func TestABI_Pack(t *testing.T) {
...@@ -33,7 +34,7 @@ func TestABI_Pack(t *testing.T) { ...@@ -33,7 +34,7 @@ func TestABI_Pack(t *testing.T) {
"0x60fe47b10000000000000000000000000000000000000000000000000000000000000064", "0x60fe47b10000000000000000000000000000000000000000000000000000000000000064",
}, },
} { } {
data, err := Pack(test.input, abiData) _, data, err := Pack(test.input, abiData, false)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, test.output, common.Bytes2Hex(data)) assert.EqualValues(t, test.output, common.Bytes2Hex(data))
} }
......
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
"strings" "strings"
) )
// Argument holds the Name of the argument and the corresponding type. // Argument holds the name of the argument and the corresponding type.
// Types are used when packing and testing arguments. // Types are used when packing and testing arguments.
type Argument struct { type Argument struct {
Name string Name string
...@@ -31,6 +31,7 @@ type Argument struct { ...@@ -31,6 +31,7 @@ type Argument struct {
Indexed bool // indexed is only used by events Indexed bool // indexed is only used by events
} }
// Arguments Argument slice type
type Arguments []Argument type Arguments []Argument
// UnmarshalJSON implements json.Unmarshaler interface // UnmarshalJSON implements json.Unmarshaler interface
...@@ -86,7 +87,7 @@ func (arguments Arguments) isTuple() bool { ...@@ -86,7 +87,7 @@ func (arguments Arguments) isTuple() bool {
// Unpack performs the operation hexdata -> Go format // Unpack performs the operation hexdata -> Go format
func (arguments Arguments) Unpack(v interface{}, data []byte) error { func (arguments Arguments) Unpack(v interface{}, data []byte) error {
// make sure the passed Value is arguments pointer // make sure the passed value is arguments pointer
if reflect.Ptr != reflect.ValueOf(v).Kind() { if reflect.Ptr != reflect.ValueOf(v).Kind() {
return fmt.Errorf("abi: Unpack(non-pointer %T)", v) return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
} }
...@@ -152,10 +153,10 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa ...@@ -152,10 +153,10 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
return nil return nil
} }
// unpackAtomic unpacks ( hexdata -> go ) a single Value // unpackAtomic unpacks ( hexdata -> go ) a single value
func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interface{}) error { func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interface{}) error {
if len(marshalledValues) != 1 { if len(marshalledValues) != 1 {
return fmt.Errorf("abi: wrong length, expected single Value, got %d", len(marshalledValues)) return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues))
} }
elem := reflect.ValueOf(v).Elem() elem := reflect.ValueOf(v).Elem()
...@@ -267,7 +268,7 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) { ...@@ -267,7 +268,7 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) {
// will be appended at the end of the input. // will be appended at the end of the input.
variableInput = append(variableInput, packed...) variableInput = append(variableInput, packed...)
} else { } else {
// append the packed Value to the input // append the packed value to the input
ret = append(ret, packed...) ret = append(ret, packed...)
} }
} }
......
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
) )
var ( var (
errBadBool = errors.New("abi: improperly encoded boolean Value") errBadBool = errors.New("abi: improperly encoded boolean value")
) )
// formatSliceString formats the reflection kind with the given slice size // formatSliceString formats the reflection kind with the given slice size
...@@ -60,7 +60,7 @@ func sliceTypeCheck(t Type, val reflect.Value) error { ...@@ -60,7 +60,7 @@ func sliceTypeCheck(t Type, val reflect.Value) error {
return nil return nil
} }
// typeCheck checks that the given reflection Value can be assigned to the reflection // typeCheck checks that the given reflection value can be assigned to the reflection
// type in t. // type in t.
func typeCheck(t Type, value reflect.Value) error { func typeCheck(t Type, value reflect.Value) error {
if t.T == SliceTy || t.T == ArrayTy { if t.T == SliceTy || t.T == ArrayTy {
......
...@@ -44,9 +44,9 @@ func (e Event) String() string { ...@@ -44,9 +44,9 @@ func (e Event) String() string {
return fmt.Sprintf("e %v(%v)", e.Name, strings.Join(inputs, ", ")) return fmt.Sprintf("e %v(%v)", e.Name, strings.Join(inputs, ", "))
} }
// Id returns the canonical representation of the event's signature used by the // ID returns the canonical representation of the event's signature used by the
// abi definition to identify event names and types. // abi definition to identify event names and types.
func (e Event) Id() common.Hash { func (e Event) ID() common.Hash {
types := make([]string, len(e.Inputs)) types := make([]string, len(e.Inputs))
i := 0 i := 0
for _, input := range e.Inputs { for _, input := range e.Inputs {
......
...@@ -35,39 +35,39 @@ var jsonEventTransfer = []byte(`{ ...@@ -35,39 +35,39 @@ var jsonEventTransfer = []byte(`{
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
{ {
"indexed": true, "Name": "from", "type": "address" "indexed": true, "name": "from", "type": "address"
}, { }, {
"indexed": true, "Name": "to", "type": "address" "indexed": true, "name": "to", "type": "address"
}, { }, {
"indexed": false, "Name": "Value", "type": "uint256" "indexed": false, "name": "value", "type": "uint256"
}], }],
"Name": "Transfer", "name": "Transfer",
"type": "event" "type": "event"
}`) }`)
var jsonEventPledge = []byte(`{ var jsonEventPledge = []byte(`{
"anonymous": false, "anonymous": false,
"inputs": [{ "inputs": [{
"indexed": false, "Name": "who", "type": "address" "indexed": false, "name": "who", "type": "address"
}, { }, {
"indexed": false, "Name": "wad", "type": "uint128" "indexed": false, "name": "wad", "type": "uint128"
}, { }, {
"indexed": false, "Name": "currency", "type": "bytes3" "indexed": false, "name": "currency", "type": "bytes3"
}], }],
"Name": "Pledge", "name": "Pledge",
"type": "event" "type": "event"
}`) }`)
var jsonEventMixedCase = []byte(`{ var jsonEventMixedCase = []byte(`{
"anonymous": false, "anonymous": false,
"inputs": [{ "inputs": [{
"indexed": false, "Name": "Value", "type": "uint256" "indexed": false, "name": "value", "type": "uint256"
}, { }, {
"indexed": false, "Name": "_value", "type": "uint256" "indexed": false, "name": "_value", "type": "uint256"
}, { }, {
"indexed": false, "Name": "Value", "type": "uint256" "indexed": false, "name": "Value", "type": "uint256"
}], }],
"Name": "MixedCase", "name": "MixedCase",
"type": "event" "type": "event"
}`) }`)
...@@ -87,8 +87,8 @@ func TestEventId(t *testing.T) { ...@@ -87,8 +87,8 @@ func TestEventId(t *testing.T) {
}{ }{
{ {
definition: `[ definition: `[
{ "type" : "event", "Name" : "balance", "inputs": [{ "Name" : "in", "type": "uint256" }] }, { "type" : "event", "name" : "balance", "inputs": [{ "name" : "in", "type": "uint256" }] },
{ "type" : "event", "Name" : "check", "inputs": [{ "Name" : "t", "type": "address" }, { "Name": "b", "type": "uint256" }] } { "type" : "event", "name" : "check", "inputs": [{ "name" : "t", "type": "address" }, { "name": "b", "type": "uint256" }] }
]`, ]`,
expectations: map[string]common.Hash{ expectations: map[string]common.Hash{
"balance": crypto.Keccak256Hash([]byte("balance(uint256)")), "balance": crypto.Keccak256Hash([]byte("balance(uint256)")),
...@@ -104,8 +104,8 @@ func TestEventId(t *testing.T) { ...@@ -104,8 +104,8 @@ func TestEventId(t *testing.T) {
} }
for name, event := range abi.Events { for name, event := range abi.Events {
if event.Id() != test.expectations[name] { if event.ID() != test.expectations[name] {
t.Errorf("expected id to be %x, got %x", test.expectations[name], event.Id()) t.Errorf("expected id to be %x, got %x", test.expectations[name], event.ID())
} }
} }
} }
...@@ -113,7 +113,7 @@ func TestEventId(t *testing.T) { ...@@ -113,7 +113,7 @@ func TestEventId(t *testing.T) {
// TestEventMultiValueWithArrayUnpack verifies that array fields will be counted after parsing array. // TestEventMultiValueWithArrayUnpack verifies that array fields will be counted after parsing array.
func TestEventMultiValueWithArrayUnpack(t *testing.T) { func TestEventMultiValueWithArrayUnpack(t *testing.T) {
definition := `[{"Name": "test", "type": "event", "inputs": [{"indexed": false, "Name":"value1", "type":"uint8[2]"},{"indexed": false, "Name":"value2", "type":"uint8"}]}]` definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": false, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"uint8"}]}]`
type testStruct struct { type testStruct struct {
Value1 [2]uint8 Value1 [2]uint8
Value2 uint8 Value2 uint8
...@@ -138,20 +138,20 @@ func TestEventTupleUnpack(t *testing.T) { ...@@ -138,20 +138,20 @@ func TestEventTupleUnpack(t *testing.T) {
} }
type EventTransferWithTag struct { type EventTransferWithTag struct {
// this is valid because `Value` is not exportable, // this is valid because `value` is not exportable,
// so Value is only unmarshalled into `Value1`. // so value is only unmarshalled into `Value1`.
value *big.Int value *big.Int
Value1 *big.Int `abi:"Value"` Value1 *big.Int `abi:"value"`
} }
type BadEventTransferWithSameFieldAndTag struct { type BadEventTransferWithSameFieldAndTag struct {
Value *big.Int Value *big.Int
Value1 *big.Int `abi:"Value"` Value1 *big.Int `abi:"value"`
} }
type BadEventTransferWithDuplicatedTag struct { type BadEventTransferWithDuplicatedTag struct {
Value1 *big.Int `abi:"Value"` Value1 *big.Int `abi:"value"`
Value2 *big.Int `abi:"Value"` Value2 *big.Int `abi:"value"`
} }
type BadEventTransferWithEmptyTag struct { type BadEventTransferWithEmptyTag struct {
...@@ -159,7 +159,7 @@ func TestEventTupleUnpack(t *testing.T) { ...@@ -159,7 +159,7 @@ func TestEventTupleUnpack(t *testing.T) {
} }
type EventPledge struct { type EventPledge struct {
Who common.Hash160Address Who common.Hash160Address
Wad *big.Int Wad *big.Int
Currency [3]byte Currency [3]byte
} }
...@@ -171,7 +171,7 @@ func TestEventTupleUnpack(t *testing.T) { ...@@ -171,7 +171,7 @@ func TestEventTupleUnpack(t *testing.T) {
} }
type EventMixedCase struct { type EventMixedCase struct {
Value1 *big.Int `abi:"Value"` Value1 *big.Int `abi:"value"`
Value2 *big.Int `abi:"_value"` Value2 *big.Int `abi:"_value"`
Value3 *big.Int `abi:"Value"` Value3 *big.Int `abi:"Value"`
} }
...@@ -221,7 +221,7 @@ func TestEventTupleUnpack(t *testing.T) { ...@@ -221,7 +221,7 @@ func TestEventTupleUnpack(t *testing.T) {
&BadEventTransferWithSameFieldAndTag{}, &BadEventTransferWithSameFieldAndTag{},
&BadEventTransferWithSameFieldAndTag{}, &BadEventTransferWithSameFieldAndTag{},
jsonEventTransfer, jsonEventTransfer,
"abi: multiple variables maps to the same abi field 'Value'", "abi: multiple variables maps to the same abi field 'value'",
"Can not unpack ERC20 Transfer event with a field and a tag mapping to the same abi variable", "Can not unpack ERC20 Transfer event with a field and a tag mapping to the same abi variable",
}, { }, {
transferData1, transferData1,
...@@ -242,7 +242,7 @@ func TestEventTupleUnpack(t *testing.T) { ...@@ -242,7 +242,7 @@ func TestEventTupleUnpack(t *testing.T) {
"Can unpack Pledge event into structure", "Can unpack Pledge event into structure",
}, { }, {
pledgeData1, pledgeData1,
&[]interface{}{& common.Hash160Address{}, &bigint, &[3]byte{}}, &[]interface{}{&common.Hash160Address{}, &bigint, &[3]byte{}},
&[]interface{}{ &[]interface{}{
&addr, &addr,
&bigintExpected2, &bigintExpected2,
...@@ -252,7 +252,7 @@ func TestEventTupleUnpack(t *testing.T) { ...@@ -252,7 +252,7 @@ func TestEventTupleUnpack(t *testing.T) {
"Can unpack Pledge event into slice", "Can unpack Pledge event into slice",
}, { }, {
pledgeData1, pledgeData1,
&[3]interface{}{& common.Hash160Address{}, &bigint, &[3]byte{}}, &[3]interface{}{&common.Hash160Address{}, &bigint, &[3]byte{}},
&[3]interface{}{ &[3]interface{}{
&addr, &addr,
&bigintExpected2, &bigintExpected2,
...@@ -276,7 +276,7 @@ func TestEventTupleUnpack(t *testing.T) { ...@@ -276,7 +276,7 @@ func TestEventTupleUnpack(t *testing.T) {
"Can not unpack Pledge event into struct with wrong filed types", "Can not unpack Pledge event into struct with wrong filed types",
}, { }, {
pledgeData1, pledgeData1,
&[]interface{}{ common.Hash160Address{}, new(big.Int)}, &[]interface{}{common.Hash160Address{}, new(big.Int)},
&[]interface{}{}, &[]interface{}{},
jsonEventPledge, jsonEventPledge,
"abi: insufficient number of elements in the list/array for unpack, want 3, got 2", "abi: insufficient number of elements in the list/array for unpack, want 3, got 2",
...@@ -357,7 +357,7 @@ func (tc testCase) encoded(intType, arrayType Type) []byte { ...@@ -357,7 +357,7 @@ func (tc testCase) encoded(intType, arrayType Type) []byte {
// TestEventUnpackIndexed verifies that indexed field will be skipped by event decoder. // TestEventUnpackIndexed verifies that indexed field will be skipped by event decoder.
func TestEventUnpackIndexed(t *testing.T) { func TestEventUnpackIndexed(t *testing.T) {
definition := `[{"Name": "test", "type": "event", "inputs": [{"indexed": true, "Name":"value1", "type":"uint8"},{"indexed": false, "Name":"value2", "type":"uint8"}]}]` definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8"},{"indexed": false, "name":"value2", "type":"uint8"}]}]`
type testStruct struct { type testStruct struct {
Value1 uint8 Value1 uint8
Value2 uint8 Value2 uint8
...@@ -374,7 +374,7 @@ func TestEventUnpackIndexed(t *testing.T) { ...@@ -374,7 +374,7 @@ func TestEventUnpackIndexed(t *testing.T) {
// TestEventIndexedWithArrayUnpack verifies that decoder will not overlow when static array is indexed input. // TestEventIndexedWithArrayUnpack verifies that decoder will not overlow when static array is indexed input.
func TestEventIndexedWithArrayUnpack(t *testing.T) { func TestEventIndexedWithArrayUnpack(t *testing.T) {
definition := `[{"Name": "test", "type": "event", "inputs": [{"indexed": true, "Name":"value1", "type":"uint8[2]"},{"indexed": false, "Name":"value2", "type":"string"}]}]` definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"string"}]}]`
type testStruct struct { type testStruct struct {
Value1 [2]uint8 Value1 [2]uint8
Value2 string Value2 string
......
...@@ -72,6 +72,7 @@ func (method Method) String() string { ...@@ -72,6 +72,7 @@ func (method Method) String() string {
return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.Name, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.Name, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", "))
} }
func (method Method) Id() []byte { // ID method name hash
func (method Method) ID() []byte {
return crypto.Keccak256([]byte(method.Sig()))[:4] return crypto.Keccak256([]byte(method.Sig()))[:4]
} }
...@@ -30,7 +30,7 @@ func packBytesSlice(bytes []byte, l int) []byte { ...@@ -30,7 +30,7 @@ func packBytesSlice(bytes []byte, l int) []byte {
return append(len, common.RightPadBytes(bytes, (l+31)/32*32)...) return append(len, common.RightPadBytes(bytes, (l+31)/32*32)...)
} }
// packElement packs the given reflect Value according to the abi specification in // packElement packs the given reflect value according to the abi specification in
// t. // t.
func packElement(t Type, reflectValue reflect.Value) []byte { func packElement(t Type, reflectValue reflect.Value) []byte {
switch t.T { switch t.T {
...@@ -64,7 +64,7 @@ func packElement(t Type, reflectValue reflect.Value) []byte { ...@@ -64,7 +64,7 @@ func packElement(t Type, reflectValue reflect.Value) []byte {
} }
} }
// packNum packs the given number (using the reflect Value) and will cast it to appropriate number representation // packNum packs the given number (using the reflect value) and will cast it to appropriate number representation
func packNum(value reflect.Value) []byte { func packNum(value reflect.Value) []byte {
switch kind := value.Kind(); kind { switch kind := value.Kind(); kind {
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
......
...@@ -306,7 +306,7 @@ func TestPack(t *testing.T) { ...@@ -306,7 +306,7 @@ func TestPack(t *testing.T) {
}, },
{ {
"address[]", "address[]",
[] common.Hash160Address{{1}, {2}}, []common.Hash160Address{{1}, {2}},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000"), common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000"),
}, },
{ {
...@@ -347,7 +347,7 @@ func TestMethodPack(t *testing.T) { ...@@ -347,7 +347,7 @@ func TestMethodPack(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
sig := abi.Methods["slice"].Id() sig := abi.Methods["slice"].ID()
sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
...@@ -360,14 +360,14 @@ func TestMethodPack(t *testing.T) { ...@@ -360,14 +360,14 @@ func TestMethodPack(t *testing.T) {
t.Errorf("expected %x got %x", sig, packed) t.Errorf("expected %x got %x", sig, packed)
} }
var addrA, addrB = common.Hash160Address{1}, common.Hash160Address{2} var addrA, addrB = common.Hash160Address{1}, common.Hash160Address{2}
sig = abi.Methods["sliceAddress"].Id() sig = abi.Methods["sliceAddress"].ID()
sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...)
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
sig = append(sig, common.LeftPadBytes(addrA[:], 32)...) sig = append(sig, common.LeftPadBytes(addrA[:], 32)...)
sig = append(sig, common.LeftPadBytes(addrB[:], 32)...) sig = append(sig, common.LeftPadBytes(addrB[:], 32)...)
packed, err = abi.Pack("sliceAddress", [] common.Hash160Address{addrA, addrB}) packed, err = abi.Pack("sliceAddress", []common.Hash160Address{addrA, addrB})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -375,8 +375,8 @@ func TestMethodPack(t *testing.T) { ...@@ -375,8 +375,8 @@ func TestMethodPack(t *testing.T) {
t.Errorf("expected %x got %x", sig, packed) t.Errorf("expected %x got %x", sig, packed)
} }
var addrC, addrD = common.Hash160Address{3}, common.Hash160Address{4} var addrC, addrD = common.Hash160Address{3}, common.Hash160Address{4}
sig = abi.Methods["sliceMultiAddress"].Id() sig = abi.Methods["sliceMultiAddress"].ID()
sig = append(sig, common.LeftPadBytes([]byte{64}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{64}, 32)...)
sig = append(sig, common.LeftPadBytes([]byte{160}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{160}, 32)...)
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
...@@ -386,7 +386,7 @@ func TestMethodPack(t *testing.T) { ...@@ -386,7 +386,7 @@ func TestMethodPack(t *testing.T) {
sig = append(sig, common.LeftPadBytes(addrC[:], 32)...) sig = append(sig, common.LeftPadBytes(addrC[:], 32)...)
sig = append(sig, common.LeftPadBytes(addrD[:], 32)...) sig = append(sig, common.LeftPadBytes(addrD[:], 32)...)
packed, err = abi.Pack("sliceMultiAddress", [] common.Hash160Address{addrA, addrB}, [] common.Hash160Address{addrC, addrD}) packed, err = abi.Pack("sliceMultiAddress", []common.Hash160Address{addrA, addrB}, []common.Hash160Address{addrC, addrD})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -394,7 +394,7 @@ func TestMethodPack(t *testing.T) { ...@@ -394,7 +394,7 @@ func TestMethodPack(t *testing.T) {
t.Errorf("expected %x got %x", sig, packed) t.Errorf("expected %x got %x", sig, packed)
} }
sig = abi.Methods["slice256"].Id() sig = abi.Methods["slice256"].ID()
sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
......
...@@ -22,7 +22,7 @@ import ( ...@@ -22,7 +22,7 @@ import (
"strings" "strings"
) )
// indirect recursively dereferences the Value until it either gets the Value // indirect recursively dereferences the value until it either gets the value
// or finds a big.Int // or finds a big.Int
func indirect(v reflect.Value) reflect.Value { func indirect(v reflect.Value) reflect.Value {
if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT { if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT {
...@@ -59,8 +59,8 @@ func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) ...@@ -59,8 +59,8 @@ func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type)
return reflect.Ptr, bigT return reflect.Ptr, bigT
} }
// mustArrayToBytesSlice creates a new byte slice with the exact same size as Value // mustArrayToBytesSlice creates a new byte slice with the exact same size as value
// and copies the bytes in Value to the new slice. // and copies the bytes in value to the new slice.
func mustArrayToByteSlice(value reflect.Value) reflect.Value { func mustArrayToByteSlice(value reflect.Value) reflect.Value {
slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len()) slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len())
reflect.Copy(slice, value) reflect.Copy(slice, value)
...@@ -114,7 +114,7 @@ func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, ...@@ -114,7 +114,7 @@ func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind,
// mapAbiToStringField maps abi to struct fields. // mapAbiToStringField maps abi to struct fields.
// first round: for each Exportable field that contains a `abi:""` tag // first round: for each Exportable field that contains a `abi:""` tag
// and this field Name exists in the arguments, pair them together. // and this field name exists in the arguments, pair them together.
// second round: for each argument field that has not been already linked, // second round: for each argument field that has not been already linked,
// find what variable is expected to be mapped into, if it exists and has not been // find what variable is expected to be mapped into, if it exists and has not been
// used, pair them. // used, pair them.
...@@ -178,9 +178,9 @@ func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]strin ...@@ -178,9 +178,9 @@ func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]strin
} }
// this abi has already been paired, skip it... unless there exists another, yet unassigned // this abi has already been paired, skip it... unless there exists another, yet unassigned
// struct field with the same field Name. If so, raise an error: // struct field with the same field name. If so, raise an error:
// abi: [ { "Name": "Value" } ] // abi: [ { "name": "value" } ]
// struct { Value *big.Int , Value1 *big.Int `abi:"Value"`} // struct { Value *big.Int , Value1 *big.Int `abi:"value"`}
if abi2struct[abiFieldName] != "" { if abi2struct[abiFieldName] != "" {
if abi2struct[abiFieldName] != structFieldName && if abi2struct[abiFieldName] != structFieldName &&
struct2abi[structFieldName] == "" && struct2abi[structFieldName] == "" &&
...@@ -201,7 +201,7 @@ func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]strin ...@@ -201,7 +201,7 @@ func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]strin
struct2abi[structFieldName] = abiFieldName struct2abi[structFieldName] = abiFieldName
} else { } else {
// not paired, but annotate as used, to detect cases like // not paired, but annotate as used, to detect cases like
// abi : [ { "Name": "Value" }, { "Name": "_value" } ] // abi : [ { "name": "value" }, { "name": "_value" } ]
// struct { Value *big.Int } // struct { Value *big.Int }
struct2abi[structFieldName] = abiFieldName struct2abi[structFieldName] = abiFieldName
} }
......
...@@ -84,8 +84,8 @@ func TestTypeRegexp(t *testing.T) { ...@@ -84,8 +84,8 @@ func TestTypeRegexp(t *testing.T) {
{"string[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]string{}), Elem: &Type{Kind: reflect.String, Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, {"string[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]string{}), Elem: &Type{Kind: reflect.String, Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}},
{"string[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, {"string[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}},
{"address", Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, {"address", Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}},
{"address[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([] common.Hash160Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, {"address[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]common.Hash160Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}},
{"address[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2] common.Hash160Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, {"address[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Hash160Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}},
// TODO when fixed types are implemented properly // TODO when fixed types are implemented properly
// {"fixed", Type{}}, // {"fixed", Type{}},
// {"fixed128x128", Type{}}, // {"fixed128x128", Type{}},
...@@ -102,7 +102,7 @@ func TestTypeRegexp(t *testing.T) { ...@@ -102,7 +102,7 @@ func TestTypeRegexp(t *testing.T) {
} }
if !reflect.DeepEqual(typ, tt.kind) { if !reflect.DeepEqual(typ, tt.kind) {
//t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", tt.blob, spew.Sdump(typeWithoutStringer(typ)), spew.Sdump(typeWithoutStringer(tt.kind))) //t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", tt.blob, spew.Sdump(typeWithoutStringer(typ)), spew.Sdump(typeWithoutStringer(tt.kind)))
t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", tt.blob, typeWithoutStringer(typ), typeWithoutStringer(tt.kind)) t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", tt.blob, typ, tt.kind)
} }
} }
} }
...@@ -201,10 +201,10 @@ func TestTypeCheck(t *testing.T) { ...@@ -201,10 +201,10 @@ func TestTypeCheck(t *testing.T) {
{"uint16[3]", [4]uint16{1, 2, 3}, "abi: cannot use [4]uint16 as type [3]uint16 as argument"}, {"uint16[3]", [4]uint16{1, 2, 3}, "abi: cannot use [4]uint16 as type [3]uint16 as argument"},
{"uint16[3]", []uint16{1, 2, 3}, ""}, {"uint16[3]", []uint16{1, 2, 3}, ""},
{"uint16[3]", []uint16{1, 2, 3, 4}, "abi: cannot use [4]uint16 as type [3]uint16 as argument"}, {"uint16[3]", []uint16{1, 2, 3, 4}, "abi: cannot use [4]uint16 as type [3]uint16 as argument"},
{"address[]", [] common.Hash160Address{{1}}, ""}, {"address[]", []common.Hash160Address{{1}}, ""},
{"address[1]", [] common.Hash160Address{{1}}, ""}, {"address[1]", []common.Hash160Address{{1}}, ""},
{"address[1]", [1] common.Hash160Address{{1}}, ""}, {"address[1]", [1]common.Hash160Address{{1}}, ""},
{"address[2]", [1] common.Hash160Address{{1}}, "abi: cannot use [1]array as type [2]array as argument"}, {"address[2]", [1]common.Hash160Address{{1}}, "abi: cannot use [1]array as type [2]array as argument"},
{"bytes32", [32]byte{}, ""}, {"bytes32", [32]byte{}, ""},
{"bytes31", [31]byte{}, ""}, {"bytes31", [31]byte{}, ""},
{"bytes30", [30]byte{}, ""}, {"bytes30", [30]byte{}, ""},
...@@ -249,9 +249,9 @@ func TestTypeCheck(t *testing.T) { ...@@ -249,9 +249,9 @@ func TestTypeCheck(t *testing.T) {
{"string", []byte{}, "abi: cannot use slice as type string as argument"}, {"string", []byte{}, "abi: cannot use slice as type string as argument"},
{"bytes32[]", [][32]byte{{}}, ""}, {"bytes32[]", [][32]byte{{}}, ""},
{"function", [24]byte{}, ""}, {"function", [24]byte{}, ""},
{"bytes20", common.Hash160Address{}, ""}, {"bytes20", common.Hash160Address{}, ""},
{"address", [20]byte{}, ""}, {"address", [20]byte{}, ""},
{"address", common.Hash160Address{}, ""}, {"address", common.Hash160Address{}, ""},
{"bytes32[]]", "", "invalid arg type in abi"}, {"bytes32[]]", "", "invalid arg type in abi"},
{"invalidType", "", "unsupported arg type: invalidType"}, {"invalidType", "", "unsupported arg type: invalidType"},
{"invalidSlice[]", "", "unsupported arg type: invalidSlice"}, {"invalidSlice[]", "", "unsupported arg type: invalidSlice"},
......
...@@ -135,7 +135,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) ...@@ -135,7 +135,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error)
return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), start+32*size) return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), start+32*size)
} }
// this Value will become our slice or our array, depending on the type // this value will become our slice or our array, depending on the type
var refSlice reflect.Value var refSlice reflect.Value
if t.T == SliceTy { if t.T == SliceTy {
...@@ -170,7 +170,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) ...@@ -170,7 +170,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error)
return refSlice.Interface(), nil return refSlice.Interface(), nil
} }
// toGoType parses the output bytes and recursively assigns the Value of these bytes // toGoType parses the output bytes and recursively assigns the value of these bytes
// into a go type with accordance with the ABI spec. // into a go type with accordance with the ABI spec.
func toGoType(index int, t Type, output []byte) (interface{}, error) { func toGoType(index int, t Type, output []byte) (interface{}, error) {
if index+32 > len(output) { if index+32 > len(output) {
......
...@@ -65,13 +65,13 @@ var unpackTests = []unpackTest{ ...@@ -65,13 +65,13 @@ var unpackTests = []unpackTest{
def: `[{ "type": "bool" }]`, def: `[{ "type": "bool" }]`,
enc: "0000000000000000000000000000000000000000000000000001000000000001", enc: "0000000000000000000000000000000000000000000000000001000000000001",
want: false, want: false,
err: "abi: improperly encoded boolean Value", err: "abi: improperly encoded boolean value",
}, },
{ {
def: `[{ "type": "bool" }]`, def: `[{ "type": "bool" }]`,
enc: "0000000000000000000000000000000000000000000000000000000000000003", enc: "0000000000000000000000000000000000000000000000000000000000000003",
want: false, want: false,
err: "abi: improperly encoded boolean Value", err: "abi: improperly encoded boolean value",
}, },
{ {
def: `[{"type": "uint32"}]`, def: `[{"type": "uint32"}]`,
...@@ -125,7 +125,7 @@ var unpackTests = []unpackTest{ ...@@ -125,7 +125,7 @@ var unpackTests = []unpackTest{
{ {
def: `[{"type": "address"}]`, def: `[{"type": "address"}]`,
enc: "0000000000000000000000000100000000000000000000000000000000000000", enc: "0000000000000000000000000100000000000000000000000000000000000000",
want: common.Hash160Address{1}, want: common.Hash160Address{1},
}, },
{ {
def: `[{"type": "bytes32"}]`, def: `[{"type": "bytes32"}]`,
...@@ -288,7 +288,7 @@ var unpackTests = []unpackTest{ ...@@ -288,7 +288,7 @@ var unpackTests = []unpackTest{
}, },
// struct outputs // struct outputs
{ {
def: `[{"Name":"int1","type":"int256"},{"Name":"int2","type":"int256"}]`, def: `[{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: struct { want: struct {
Int1 *big.Int Int1 *big.Int
...@@ -296,7 +296,7 @@ var unpackTests = []unpackTest{ ...@@ -296,7 +296,7 @@ var unpackTests = []unpackTest{
}{big.NewInt(1), big.NewInt(2)}, }{big.NewInt(1), big.NewInt(2)},
}, },
{ {
def: `[{"Name":"int","type":"int256"},{"Name":"Int","type":"int256"}]`, def: `[{"name":"int","type":"int256"},{"name":"Int","type":"int256"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: struct { want: struct {
Int1 *big.Int Int1 *big.Int
...@@ -305,7 +305,7 @@ var unpackTests = []unpackTest{ ...@@ -305,7 +305,7 @@ var unpackTests = []unpackTest{
err: "abi: multiple outputs mapping to the same struct field 'Int'", err: "abi: multiple outputs mapping to the same struct field 'Int'",
}, },
{ {
def: `[{"Name":"int","type":"int256"},{"Name":"_int","type":"int256"}]`, def: `[{"name":"int","type":"int256"},{"name":"_int","type":"int256"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: struct { want: struct {
Int1 *big.Int Int1 *big.Int
...@@ -314,7 +314,7 @@ var unpackTests = []unpackTest{ ...@@ -314,7 +314,7 @@ var unpackTests = []unpackTest{
err: "abi: multiple outputs mapping to the same struct field 'Int'", err: "abi: multiple outputs mapping to the same struct field 'Int'",
}, },
{ {
def: `[{"Name":"Int","type":"int256"},{"Name":"_int","type":"int256"}]`, def: `[{"name":"Int","type":"int256"},{"name":"_int","type":"int256"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: struct { want: struct {
Int1 *big.Int Int1 *big.Int
...@@ -323,7 +323,7 @@ var unpackTests = []unpackTest{ ...@@ -323,7 +323,7 @@ var unpackTests = []unpackTest{
err: "abi: multiple outputs mapping to the same struct field 'Int'", err: "abi: multiple outputs mapping to the same struct field 'Int'",
}, },
{ {
def: `[{"Name":"Int","type":"int256"},{"Name":"_","type":"int256"}]`, def: `[{"name":"Int","type":"int256"},{"name":"_","type":"int256"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: struct { want: struct {
Int1 *big.Int Int1 *big.Int
...@@ -336,7 +336,7 @@ var unpackTests = []unpackTest{ ...@@ -336,7 +336,7 @@ var unpackTests = []unpackTest{
func TestUnpack(t *testing.T) { func TestUnpack(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) def := fmt.Sprintf(`[{ "name" : "method", "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)
...@@ -366,7 +366,7 @@ type methodMultiOutput struct { ...@@ -366,7 +366,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", "constant" : false, "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))
...@@ -440,7 +440,7 @@ func TestMethodMultiReturn(t *testing.T) { ...@@ -440,7 +440,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", "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)
...@@ -467,7 +467,7 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { ...@@ -467,7 +467,7 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) {
// 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", "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 +504,15 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { ...@@ -504,15 +504,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", "constant" : false, "outputs": [ { "type": "uint256" } ] },
{ "Name" : "bool", "constant" : false, "outputs": [ { "type": "bool" } ] }, { "name" : "bool", "constant" : false, "outputs": [ { "type": "bool" } ] },
{ "Name" : "bytes", "constant" : false, "outputs": [ { "type": "bytes" } ] }, { "name" : "bytes", "constant" : false, "outputs": [ { "type": "bytes" } ] },
{ "Name" : "fixed", "constant" : false, "outputs": [ { "type": "bytes32" } ] }, { "name" : "fixed", "constant" : false, "outputs": [ { "type": "bytes32" } ] },
{ "Name" : "multi", "constant" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] }, { "name" : "multi", "constant" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] },
{ "Name" : "intArraySingle", "constant" : false, "outputs": [ { "type": "uint256[3]" } ] }, { "name" : "intArraySingle", "constant" : false, "outputs": [ { "type": "uint256[3]" } ] },
{ "Name" : "addressSliceSingle", "constant" : false, "outputs": [ { "type": "address[]" } ] }, { "name" : "addressSliceSingle", "constant" : false, "outputs": [ { "type": "address[]" } ] },
{ "Name" : "addressSliceDouble", "constant" : false, "outputs": [ { "Name": "a", "type": "address[]" }, { "Name": "b", "type": "address[]" } ] }, { "name" : "addressSliceDouble", "constant" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
{ "Name" : "mixedBytes", "constant" : true, "outputs": [ { "Name": "a", "type": "bytes" }, { "Name": "b", "type": "bytes32" } ] }]` { "name" : "mixedBytes", "constant" : true, "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 {
...@@ -535,11 +535,11 @@ func TestUnmarshal(t *testing.T) { ...@@ -535,11 +535,11 @@ func TestUnmarshal(t *testing.T) {
t.Error(err) t.Error(err)
} else { } else {
if !bytes.Equal(p0, p0Exp) { if !bytes.Equal(p0, p0Exp) {
t.Errorf("unexpected Value unpacked: want %x, got %x", p0Exp, p0) t.Errorf("unexpected value unpacked: want %x, got %x", p0Exp, p0)
} }
if !bytes.Equal(p1[:], p1Exp) { if !bytes.Equal(p1[:], p1Exp) {
t.Errorf("unexpected Value unpacked: want %x, got %x", p1Exp, p1) t.Errorf("unexpected value unpacked: want %x, got %x", p1Exp, p1)
} }
} }
...@@ -689,7 +689,7 @@ func TestUnmarshal(t *testing.T) { ...@@ -689,7 +689,7 @@ func TestUnmarshal(t *testing.T) {
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // size buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // size
buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000")) buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000"))
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 {
t.Fatal("didn't expect error:", err) t.Fatal("didn't expect error:", err)
...@@ -699,8 +699,8 @@ func TestUnmarshal(t *testing.T) { ...@@ -699,8 +699,8 @@ func TestUnmarshal(t *testing.T) {
t.Fatal("expected 1 item, got", len(outAddr)) t.Fatal("expected 1 item, got", len(outAddr))
} }
if outAddr[0] != ( common.Hash160Address{1}) { if outAddr[0] != (common.Hash160Address{1}) {
t.Errorf("expected %x, got %x", common.Hash160Address{1}, outAddr[0]) t.Errorf("expected %x, got %x", common.Hash160Address{1}, outAddr[0])
} }
// marshal multiple address slice // marshal multiple address slice
...@@ -714,8 +714,8 @@ func TestUnmarshal(t *testing.T) { ...@@ -714,8 +714,8 @@ func TestUnmarshal(t *testing.T) {
buff.Write(common.Hex2Bytes("0000000000000000000000000300000000000000000000000000000000000000")) buff.Write(common.Hex2Bytes("0000000000000000000000000300000000000000000000000000000000000000"))
var outAddrStruct struct { var outAddrStruct struct {
A [] common.Hash160Address A []common.Hash160Address
B [] common.Hash160Address B []common.Hash160Address
} }
err = abi.Unpack(&outAddrStruct, "addressSliceDouble", buff.Bytes()) err = abi.Unpack(&outAddrStruct, "addressSliceDouble", buff.Bytes())
if err != nil { if err != nil {
...@@ -726,19 +726,19 @@ func TestUnmarshal(t *testing.T) { ...@@ -726,19 +726,19 @@ func TestUnmarshal(t *testing.T) {
t.Fatal("expected 1 item, got", len(outAddrStruct.A)) t.Fatal("expected 1 item, got", len(outAddrStruct.A))
} }
if outAddrStruct.A[0] != ( common.Hash160Address{1}) { if outAddrStruct.A[0] != (common.Hash160Address{1}) {
t.Errorf("expected %x, got %x", common.Hash160Address{1}, outAddrStruct.A[0]) t.Errorf("expected %x, got %x", common.Hash160Address{1}, outAddrStruct.A[0])
} }
if len(outAddrStruct.B) != 2 { if len(outAddrStruct.B) != 2 {
t.Fatal("expected 1 item, got", len(outAddrStruct.B)) t.Fatal("expected 1 item, got", len(outAddrStruct.B))
} }
if outAddrStruct.B[0] != ( common.Hash160Address{2}) { if outAddrStruct.B[0] != (common.Hash160Address{2}) {
t.Errorf("expected %x, got %x", common.Hash160Address{2}, outAddrStruct.B[0]) t.Errorf("expected %x, got %x", common.Hash160Address{2}, outAddrStruct.B[0])
} }
if outAddrStruct.B[1] != ( common.Hash160Address{3}) { if outAddrStruct.B[1] != (common.Hash160Address{3}) {
t.Errorf("expected %x, got %x", common.Hash160Address{3}, outAddrStruct.B[1]) t.Errorf("expected %x, got %x", common.Hash160Address{3}, outAddrStruct.B[1])
} }
// marshal invalid address slice // marshal invalid address slice
...@@ -805,7 +805,7 @@ func TestOOMMaliciousInput(t *testing.T) { ...@@ -805,7 +805,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", "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)
......
...@@ -9,7 +9,6 @@ import ( ...@@ -9,7 +9,6 @@ import (
"strings" "strings"
"bytes"
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/evm/executor/abi" "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
...@@ -28,7 +27,12 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt, ...@@ -28,7 +27,12 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
if err != nil { if err != nil {
return nil, err return nil, err
} }
return evm.innerExec(msg, tx.Hash(), index, tx.Fee, false)
}
// 通用的EVM合约执行逻辑封装
// readOnly 是否只读调用,仅执行evm abi查询时为true
func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int, txFee int64, readOnly bool) (receipt *types.Receipt, err error) {
// 获取当前区块的上下文信息构造EVM上下文 // 获取当前区块的上下文信息构造EVM上下文
context := evm.NewEVMContext(msg) context := evm.NewEVMContext(msg)
...@@ -42,7 +46,6 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt, ...@@ -42,7 +46,6 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
contractAddr common.Address contractAddr common.Address
snapshot int snapshot int
execName string execName string
abiCall bool
abiData string abiData string
methodName string methodName string
) )
...@@ -50,38 +53,38 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt, ...@@ -50,38 +53,38 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
// 为了方便计费,即使合约为新生成,也将地址的初始化放到外面操作 // 为了方便计费,即使合约为新生成,也将地址的初始化放到外面操作
if isCreate { if isCreate {
// 使用随机生成的地址作为合约地址(这个可以保证每次创建的合约地址不会重复,不存在冲突的情况) // 使用随机生成的地址作为合约地址(这个可以保证每次创建的合约地址不会重复,不存在冲突的情况)
contractAddr = evm.getNewAddr(tx.Hash()) contractAddr = evm.getNewAddr(txHash)
if !env.StateDB.Empty(contractAddr.String()) { if !env.StateDB.Empty(contractAddr.String()) {
return nil, model.ErrContractAddressCollision return receipt, model.ErrContractAddressCollision
} }
// 只有新创建的合约才能生成合约名称 // 只有新创建的合约才能生成合约名称
execName = fmt.Sprintf("%s%s", types.ExecName(evmtypes.EvmPrefix), common.BytesToHash(tx.Hash()).Hex()) execName = fmt.Sprintf("%s%s", types.ExecName(evmtypes.EvmPrefix), common.BytesToHash(txHash).Hex())
} else { } else {
contractAddr = *msg.To() contractAddr = *msg.To()
} }
// 状态机中设置当前交易状态 // 状态机中设置当前交易状态
evm.mStateDB.Prepare(common.BytesToHash(tx.Hash()), index) evm.mStateDB.Prepare(common.BytesToHash(txHash), index)
if isCreate { if isCreate {
ret, snapshot, leftOverGas, vmerr = env.Create(runtime.AccountRef(msg.From()), contractAddr, msg.Data(), context.GasLimit, execName, msg.Alias()) // 如果携带ABI数据,则对数据合法性进行检查
} else { if len(msg.ABI()) > 0 && types.IsDappFork(evm.GetHeight(), "evm", "ForkEVMABI") {
inData := msg.Data() _, err = abi.JSON(strings.NewReader(abiData))
//TODO 在这里进行ABI和十六进制的调用参数转换
if bytes.HasPrefix(msg.Data(), evmtypes.ABICallPrefix) {
abiCall = true
callData := msg.Data()[len(evmtypes.ABICallPrefix):]
abiDataBin, err := evm.GetStateDB().Get(getABIKey(*msg.To()))
if err != nil { if err != nil {
return nil, err return receipt, err
} }
abiData = string(abiDataBin) }
funcName, packData, err := abi.Pack(string(callData), abiData) ret, snapshot, leftOverGas, vmerr = env.Create(runtime.AccountRef(msg.From()), contractAddr, msg.Data(), context.GasLimit, execName, msg.Alias(), msg.ABI())
} else {
inData := msg.Data()
// 在这里进行ABI和十六进制的调用参数转换
if len(msg.ABI()) > 0 && types.IsDappFork(evm.GetHeight(), "evm", "ForkEVMABI") {
funcName, packData, err := abi.Pack(msg.ABI(), evm.mStateDB.GetAbi(msg.To().String()), readOnly)
if err != nil { if err != nil {
return nil, err return receipt, err
} }
methodName = funcName
inData = packData inData = packData
methodName = funcName
} }
ret, snapshot, leftOverGas, vmerr = env.Call(runtime.AccountRef(msg.From()), *msg.To(), inData, context.GasLimit, msg.Value()) ret, snapshot, leftOverGas, vmerr = env.Call(runtime.AccountRef(msg.From()), *msg.To(), inData, context.GasLimit, msg.Value())
} }
...@@ -98,34 +101,40 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt, ...@@ -98,34 +101,40 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
if vmerr != nil { if vmerr != nil {
log.Error("evm contract exec error", "error info", vmerr) log.Error("evm contract exec error", "error info", vmerr)
return nil, vmerr return receipt, vmerr
} }
// 计算消耗了多少费用(实际消耗的费用) // 计算消耗了多少费用(实际消耗的费用)
usedFee, overflow := common.SafeMul(usedGas, uint64(msg.GasPrice())) usedFee, overflow := common.SafeMul(usedGas, uint64(msg.GasPrice()))
// 费用消耗溢出,执行失败 // 费用消耗溢出,执行失败
if overflow || usedFee > uint64(tx.Fee) { if overflow || usedFee > uint64(txFee) {
// 如果操作没有回滚,则在这里处理 // 如果操作没有回滚,则在这里处理
if curVer != nil && snapshot >= curVer.GetID() && curVer.GetID() > -1 { if curVer != nil && snapshot >= curVer.GetID() && curVer.GetID() > -1 {
evm.mStateDB.RevertToSnapshot(snapshot) evm.mStateDB.RevertToSnapshot(snapshot)
} }
return nil, model.ErrOutOfGas return receipt, model.ErrOutOfGas
} }
// 打印合约中生成的日志 // 打印合约中生成的日志
evm.mStateDB.PrintLogs() evm.mStateDB.PrintLogs()
// 没有任何数据变更
if curVer == nil { if curVer == nil {
return nil, nil return receipt, nil
} }
// 从状态机中获取数据变更和变更日志
data, logs := evm.mStateDB.GetChangedData(curVer.GetID())
// TODO 在这里进行调用结果的转换 // 从状态机中获取数据变更和变更日志
if abiCall { kvSet, logs := evm.mStateDB.GetChangedData(curVer.GetID())
}
contractReceipt := &evmtypes.ReceiptEVMContract{Caller: msg.From().String(), ContractName: execName, ContractAddr: contractAddr.String(), UsedGas: usedGas, Ret: ret} contractReceipt := &evmtypes.ReceiptEVMContract{Caller: msg.From().String(), ContractName: execName, ContractAddr: contractAddr.String(), UsedGas: usedGas, Ret: ret}
// 这里进行ABI调用结果格式化
if len(methodName) > 0 && len(msg.ABI()) > 0 && types.IsDappFork(evm.GetHeight(), "evm", "ForkEVMABI") {
jsonRet, err := abi.Unpack(ret, methodName, evm.mStateDB.GetAbi(msg.To().String()))
if err != nil {
// 这里出错不影响整体执行,只打印错误信息
log.Error("unpack evm return error", "error", err)
}
contractReceipt.JsonRet = jsonRet
}
logs = append(logs, &types.ReceiptLog{Ty: evmtypes.TyLogCallContract, Log: types.Encode(contractReceipt)}) logs = append(logs, &types.ReceiptLog{Ty: evmtypes.TyLogCallContract, Log: types.Encode(contractReceipt)})
logs = append(logs, evm.mStateDB.GetReceiptLogs(contractAddr.String())...) logs = append(logs, evm.mStateDB.GetReceiptLogs(contractAddr.String())...)
...@@ -133,21 +142,11 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt, ...@@ -133,21 +142,11 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
// 将执行时生成的合约状态数据变更信息也计算哈希并保存 // 将执行时生成的合约状态数据变更信息也计算哈希并保存
hashKV := evm.calcKVHash(contractAddr, logs) hashKV := evm.calcKVHash(contractAddr, logs)
if hashKV != nil { if hashKV != nil {
data = append(data, hashKV) kvSet = append(kvSet, hashKV)
}
}
// 尝试从交易备注中获取ABI数据
if isCreate && types.IsDappFork(evm.GetHeight(), "evm", "ForkEVMABI") {
_, err = abi.JSON(strings.NewReader(msg.ABI()))
if err == nil {
data = append(data, evm.getABIKV(contractAddr, msg.ABI()))
} else {
log.Debug("invalid abi data in transaction note", "note", msg.ABI())
} }
} }
receipt := &types.Receipt{Ty: types.ExecOk, KV: data, Logs: logs} receipt = &types.Receipt{Ty: types.ExecOk, KV: kvSet, Logs: logs}
// 返回之前,把本次交易在区块中生成的合约日志集中打印出来 // 返回之前,把本次交易在区块中生成的合约日志集中打印出来
if evm.mStateDB != nil { if evm.mStateDB != nil {
...@@ -155,9 +154,10 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt, ...@@ -155,9 +154,10 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
} }
// 替换导致分叉的执行数据信息 // 替换导致分叉的执行数据信息
state.ProcessFork(evm.GetHeight(), tx.Hash(), receipt) state.ProcessFork(evm.GetHeight(), txHash, receipt)
evm.collectEvmTxLog(txHash, contractReceipt, receipt)
evm.collectEvmTxLog(tx, contractReceipt, receipt)
return receipt, nil return receipt, nil
} }
...@@ -173,22 +173,17 @@ func (evm *EVMExecutor) GetMessage(tx *types.Transaction) (msg *common.Message, ...@@ -173,22 +173,17 @@ func (evm *EVMExecutor) GetMessage(tx *types.Transaction) (msg *common.Message,
var action evmtypes.EVMContractAction var action evmtypes.EVMContractAction
err = types.Decode(tx.Payload, &action) err = types.Decode(tx.Payload, &action)
if err != nil { if err != nil {
return nil, err return msg, err
} }
// 此处暂时不考虑消息发送签名的处理,chain33在mempool中对签名做了检查 // 此处暂时不考虑消息发送签名的处理,chain33在mempool中对签名做了检查
from := getCaller(tx) from := getCaller(tx)
to := getReceiver(tx) to := getReceiver(tx)
if to == nil { if to == nil {
return nil, types.ErrInvalidAddress return msg, types.ErrInvalidAddress
} }
// 注意Transaction中的payload内容同时包含转账金额和合约代码
// payload[:8]为转账金额,payload[8:]为合约代码
amount := action.Amount
gasLimit := action.GasLimit gasLimit := action.GasLimit
gasPrice := action.GasPrice gasPrice := action.GasPrice
code := action.Code
if gasLimit == 0 { if gasLimit == 0 {
gasLimit = uint64(tx.Fee) gasLimit = uint64(tx.Fee)
} }
...@@ -197,13 +192,13 @@ func (evm *EVMExecutor) GetMessage(tx *types.Transaction) (msg *common.Message, ...@@ -197,13 +192,13 @@ func (evm *EVMExecutor) GetMessage(tx *types.Transaction) (msg *common.Message,
} }
// 合约的GasLimit即为调用者为本次合约调用准备支付的手续费 // 合约的GasLimit即为调用者为本次合约调用准备支付的手续费
msg = common.NewMessage(from, to, tx.Nonce, amount, gasLimit, gasPrice, code, action.GetAlias(), action.Note) msg = common.NewMessage(from, to, tx.Nonce, action.Amount, gasLimit, gasPrice, action.Code, action.GetAlias(), action.Abi)
return msg, nil return msg, err
} }
func (evm *EVMExecutor) collectEvmTxLog(tx *types.Transaction, cr *evmtypes.ReceiptEVMContract, receipt *types.Receipt) { func (evm *EVMExecutor) collectEvmTxLog(txHash []byte, cr *evmtypes.ReceiptEVMContract, receipt *types.Receipt) {
log.Debug("evm collect begin") log.Debug("evm collect begin")
log.Debug("Tx info", "txHash", common.Bytes2Hex(tx.Hash()), "height", evm.GetHeight()) log.Debug("Tx info", "txHash", common.Bytes2Hex(txHash), "height", evm.GetHeight())
log.Debug("ReceiptEVMContract", "data", fmt.Sprintf("caller=%v, name=%v, addr=%v, usedGas=%v, ret=%v", cr.Caller, cr.ContractName, cr.ContractAddr, cr.UsedGas, common.Bytes2Hex(cr.Ret))) log.Debug("ReceiptEVMContract", "data", fmt.Sprintf("caller=%v, name=%v, addr=%v, usedGas=%v, ret=%v", cr.Caller, cr.ContractName, cr.ContractAddr, cr.UsedGas, common.Bytes2Hex(cr.Ret)))
log.Debug("receipt data", "type", receipt.Ty) log.Debug("receipt data", "type", receipt.Ty)
for _, kv := range receipt.KV { for _, kv := range receipt.KV {
...@@ -232,18 +227,10 @@ func (evm *EVMExecutor) calcKVHash(addr common.Address, logs []*types.ReceiptLog ...@@ -232,18 +227,10 @@ func (evm *EVMExecutor) calcKVHash(addr common.Address, logs []*types.ReceiptLog
return nil return nil
} }
func (evm *EVMExecutor) getABIKV(addr common.Address, data string) (kv *types.KeyValue) {
return &types.KeyValue{Key: getABIKey(addr), Value: []byte(data)}
}
func getDataHashKey(addr common.Address) []byte { func getDataHashKey(addr common.Address) []byte {
return []byte(fmt.Sprintf("mavl-%v-data-hash:%v", evmtypes.ExecutorName, addr)) return []byte(fmt.Sprintf("mavl-%v-data-hash:%v", evmtypes.ExecutorName, addr))
} }
func getABIKey(addr common.Address) []byte {
return []byte(fmt.Sprintf("mavl-%v-data-abi:%v", evmtypes.ExecutorName, addr))
}
// 从交易信息中获取交易发起人地址 // 从交易信息中获取交易发起人地址
func getCaller(tx *types.Transaction) common.Address { func getCaller(tx *types.Transaction) common.Address {
return *common.StringToAddress(tx.From()) return *common.StringToAddress(tx.From())
......
...@@ -12,9 +12,8 @@ import ( ...@@ -12,9 +12,8 @@ import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/model" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/model"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/runtime"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/state"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types" evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
"github.com/kataras/iris/core/errors"
) )
// Query_CheckAddrExists 检查合约地址是否存在,此操作不会改变任何状态,所以可以直接从statedb查询 // Query_CheckAddrExists 检查合约地址是否存在,此操作不会改变任何状态,所以可以直接从statedb查询
...@@ -56,7 +55,6 @@ func (evm *EVMExecutor) Query_EstimateGas(in *evmtypes.EstimateEVMGasReq) (types ...@@ -56,7 +55,6 @@ func (evm *EVMExecutor) Query_EstimateGas(in *evmtypes.EstimateEVMGasReq) (types
evm.CheckInit() evm.CheckInit()
var ( var (
caller common.Address caller common.Address
to *common.Address
) )
// 如果未指定调用地址,则直接使用一个虚拟的地址发起调用 // 如果未指定调用地址,则直接使用一个虚拟的地址发起调用
...@@ -69,35 +67,36 @@ func (evm *EVMExecutor) Query_EstimateGas(in *evmtypes.EstimateEVMGasReq) (types ...@@ -69,35 +67,36 @@ func (evm *EVMExecutor) Query_EstimateGas(in *evmtypes.EstimateEVMGasReq) (types
caller = common.ExecAddress(types.ExecName(evmtypes.ExecutorName)) caller = common.ExecAddress(types.ExecName(evmtypes.ExecutorName))
} }
isCreate := strings.EqualFold(in.To, EvmAddress) msg := common.NewMessage(caller, nil, 0, in.Amount, evmtypes.MaxGasLimit, 1, in.Code, "estimateGas", in.Abi)
txHash := common.BigToHash(big.NewInt(evmtypes.MaxGasLimit)).Bytes()
msg := common.NewMessage(caller, nil, 0, in.Amount, evmtypes.MaxGasLimit, 1, in.Code, "estimateGas","") receipt, err := evm.innerExec(msg, txHash, 1, evmtypes.MaxGasLimit, false)
context := evm.NewEVMContext(msg) if err != nil {
// 创建EVM运行时对象 return nil, err
evm.mStateDB = state.NewMemoryStateDB(evm.GetStateDB(), evm.GetLocalDB(), evm.GetCoinsAccount(), evm.GetHeight()) }
env := runtime.NewEVM(context, evm.mStateDB, *evm.vmCfg)
evm.mStateDB.Prepare(common.BigToHash(big.NewInt(evmtypes.MaxGasLimit)), 0)
var (
vmerr error
leftOverGas uint64
contractAddr common.Address
execName string
)
if isCreate { if receipt.Ty == types.ExecOk {
txHash := common.BigToHash(big.NewInt(evmtypes.MaxGasLimit)).Bytes() callData := getCallReceipt(receipt.GetLogs())
contractAddr = evm.getNewAddr(txHash) if callData != nil {
execName = fmt.Sprintf("%s%s", types.ExecName(evmtypes.EvmPrefix), common.BytesToHash(txHash).Hex()) result := &evmtypes.EstimateEVMGasResp{}
_, _, leftOverGas, vmerr = env.Create(runtime.AccountRef(msg.From()), contractAddr, msg.Data(), context.GasLimit, execName, "estimateGas") result.Gas = callData.UsedGas
} else { return result, nil
to = common.StringToAddress(in.To) }
_, _, leftOverGas, vmerr = env.Call(runtime.AccountRef(msg.From()), *to, msg.Data(), context.GasLimit, msg.Value())
} }
return nil, errors.New("contract call error")
}
result := &evmtypes.EstimateEVMGasResp{} // 从日志中查找调用结果
result.Gas = evmtypes.MaxGasLimit - leftOverGas func getCallReceipt(logs []*types.ReceiptLog) (res *evmtypes.ReceiptEVMContract) {
return result, vmerr if len(logs) == 0 {
return res
}
for _, v := range logs {
if v.Ty == evmtypes.TyLogCallContract {
types.Decode(v.Log, res)
}
}
return res
} }
// Query_EvmDebug 此方法用来估算合约消耗的Gas,不能修改原有执行器的状态数据 // Query_EvmDebug 此方法用来估算合约消耗的Gas,不能修改原有执行器的状态数据
...@@ -113,3 +112,65 @@ func (evm *EVMExecutor) Query_EvmDebug(in *evmtypes.EvmDebugReq) (types.Message, ...@@ -113,3 +112,65 @@ func (evm *EVMExecutor) Query_EvmDebug(in *evmtypes.EvmDebugReq) (types.Message,
ret := &evmtypes.EvmDebugResp{DebugStatus: fmt.Sprintf("%v", evmDebug)} ret := &evmtypes.EvmDebugResp{DebugStatus: fmt.Sprintf("%v", evmDebug)}
return ret, nil return ret, nil
} }
// Query_Query 此方法用来调用合约的只读接口,不修改原有执行器的状态数据
func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, error) {
evm.CheckInit()
ret := &evmtypes.EvmQueryResp{}
ret.Address = in.Address
ret.Input = in.Input
ret.Caller = in.Caller
var (
caller common.Address
)
to := common.StringToAddress(in.Address)
if to == nil {
ret.JsonData = fmt.Sprintf("invalid address:%v", in.Address)
return ret, nil
}
// 如果未指定调用地址,则直接使用一个虚拟的地址发起调用
if len(in.Caller) > 0 {
callAddr := common.StringToAddress(in.Caller)
if callAddr != nil {
caller = *callAddr
}
} else {
caller = common.ExecAddress(types.ExecName(evmtypes.ExecutorName))
}
msg := common.NewMessage(caller, common.StringToAddress(in.Address), 0, 0, evmtypes.MaxGasLimit, 1, nil, "estimateGas", in.Input)
txHash := common.BigToHash(big.NewInt(evmtypes.MaxGasLimit)).Bytes()
receipt, err := evm.innerExec(msg, txHash, 1, evmtypes.MaxGasLimit, true)
if err != nil {
ret.JsonData = fmt.Sprintf("%v", err)
return ret, nil
}
if receipt.Ty == types.ExecOk {
callData := getCallReceipt(receipt.GetLogs())
if callData != nil {
ret.RawData = callData.Ret
ret.JsonData = callData.JsonRet
return ret, nil
}
}
return ret, nil
}
// Query_QueryABI 此方法用来查询合约绑定的ABI数据,不修改原有执行器的状态数据
func (evm *EVMExecutor) Query_QueryABI(in *evmtypes.EvmQueryAbiReq) (types.Message, error) {
evm.CheckInit()
addr := common.StringToAddress(in.GetAddress())
if addr == nil {
return nil, fmt.Errorf("invalid address: %v", in.GetAddress())
}
abiData := evm.mStateDB.GetAbi(addr.String())
return &evmtypes.EvmQueryAbiResp{Address: in.GetAddress(), Abi: abiData}, nil
}
...@@ -137,7 +137,7 @@ func runCase(tt *testing.T, c VMCase, file string) { ...@@ -137,7 +137,7 @@ func runCase(tt *testing.T, c VMCase, file string) {
ret, _, _, err = env.Call(runtime.AccountRef(msg.From()), *common.StringToAddress(c.exec.address), msg.Data(), msg.GasLimit(), msg.Value()) ret, _, _, err = env.Call(runtime.AccountRef(msg.From()), *common.StringToAddress(c.exec.address), msg.Data(), msg.GasLimit(), msg.Value())
} else { } else {
addr := crypto.RandomContractAddress() addr := crypto.RandomContractAddress()
ret, _, _, err = env.Create(runtime.AccountRef(msg.From()), *addr, msg.Data(), msg.GasLimit(), "testExecName", "") ret, _, _, err = env.Create(runtime.AccountRef(msg.From()), *addr, msg.Data(), msg.GasLimit(), "testExecName", "", "")
} }
if err != nil { if err != nil {
...@@ -200,5 +200,5 @@ func buildMsg(c VMCase) *common.Message { ...@@ -200,5 +200,5 @@ func buildMsg(c VMCase) *common.Message {
addr2 := common.StringToAddress(c.exec.address) addr2 := common.StringToAddress(c.exec.address)
gasLimit := uint64(210000000) gasLimit := uint64(210000000)
gasPrice := c.exec.gasPrice gasPrice := c.exec.gasPrice
return common.NewMessage(*addr1, addr2, int64(1), uint64(c.exec.value), gasLimit, uint32(gasPrice), code, "") return common.NewMessage(*addr1, addr2, int64(1), uint64(c.exec.value), gasLimit, uint32(gasPrice), code, "", "")
} }
...@@ -271,7 +271,7 @@ func createContract(mdb *db.GoMemDB, tx types.Transaction, maxCodeSize int) (ret ...@@ -271,7 +271,7 @@ func createContract(mdb *db.GoMemDB, tx types.Transaction, maxCodeSize int) (ret
} }
addr := *crypto2.RandomContractAddress() addr := *crypto2.RandomContractAddress()
ret, _, leftGas, err := env.Create(runtime.AccountRef(msg.From()), addr, msg.Data(), msg.GasLimit(), fmt.Sprintf("%s%s", evmtypes.EvmPrefix, common.BytesToHash(tx.Hash()).Hex()), "") ret, _, leftGas, err := env.Create(runtime.AccountRef(msg.From()), addr, msg.Data(), msg.GasLimit(), fmt.Sprintf("%s%s", evmtypes.EvmPrefix, common.BytesToHash(tx.Hash()).Hex()), "", "")
return ret, addr, leftGas, statedb, err return ret, addr, leftGas, statedb, err
} }
...@@ -7,11 +7,12 @@ package common ...@@ -7,11 +7,12 @@ package common
import ( import (
"math/big" "math/big"
"encoding/hex"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/crypto/sha3"
"github.com/33cn/chain33/common/log/log15" "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"encoding/hex"
"github.com/33cn/chain33/common/crypto/sha3"
) )
// Address 封装地址结构体,并提供各种常用操作封装 // Address 封装地址结构体,并提供各种常用操作封装
...@@ -116,14 +117,6 @@ func BytesToHash160Address(b []byte) Hash160Address { ...@@ -116,14 +117,6 @@ func BytesToHash160Address(b []byte) Hash160Address {
return h return h
} }
// BytesToAddress 字节向地址转换
func Hash160ToAddress(h Hash160Address) Address {
a := new(address.Address)
a.Version = 0
a.Hash160 = copyBytes(h[:])
return Address{addr: a}
}
// StringToAddress 字符串转换为地址 // StringToAddress 字符串转换为地址
func StringToAddress(s string) *Address { func StringToAddress(s string) *Address {
addr, err := address.NewAddrFromString(s) addr, err := address.NewAddrFromString(s)
......
...@@ -69,8 +69,7 @@ func Keccak256(data ...[]byte) []byte { ...@@ -69,8 +69,7 @@ func Keccak256(data ...[]byte) []byte {
return d.Sum(nil) return d.Sum(nil)
} }
// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
// NewKeccak256Hash calculates and returns the Keccak256 hash of the input data,
// converting it to an internal Hash data structure. // converting it to an internal Hash data structure.
func Keccak256Hash(data ...[]byte) (h common.Hash) { func Keccak256Hash(data ...[]byte) (h common.Hash) {
d := sha3.NewLegacyKeccak256() d := sha3.NewLegacyKeccak256()
...@@ -79,4 +78,4 @@ func Keccak256Hash(data ...[]byte) (h common.Hash) { ...@@ -79,4 +78,4 @@ func Keccak256Hash(data ...[]byte) (h common.Hash) {
} }
d.Sum(h[:0]) d.Sum(h[:0])
return h return h
} }
\ No newline at end of file
...@@ -356,7 +356,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte ...@@ -356,7 +356,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
// 使用传入的部署代码创建新的合约; // 使用传入的部署代码创建新的合约;
// 目前chain33为了保证账户安全,不允许合约中涉及到外部账户的转账操作, // 目前chain33为了保证账户安全,不允许合约中涉及到外部账户的转账操作,
// 所以,本步骤不接收转账金额参数 // 所以,本步骤不接收转账金额参数
func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []byte, gas uint64, execName, alias string) (ret []byte, snapshot int, leftOverGas uint64, err error) { func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []byte, gas uint64, execName, alias, abi string) (ret []byte, snapshot int, leftOverGas uint64, err error) {
pass, err := evm.preCheck(caller, contractAddr, 0) pass, err := evm.preCheck(caller, contractAddr, 0)
if !pass { if !pass {
return nil, -1, gas, err return nil, -1, gas, err
...@@ -386,6 +386,10 @@ func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []b ...@@ -386,6 +386,10 @@ func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []b
createDataGas := uint64(len(ret)) * params.CreateDataGas createDataGas := uint64(len(ret)) * params.CreateDataGas
if contract.UseGas(createDataGas) { if contract.UseGas(createDataGas) {
evm.StateDB.SetCode(contractAddr.String(), ret) evm.StateDB.SetCode(contractAddr.String(), ret)
// 设置 ABI (如果有的话),这个动作不单独计费
if len(abi) > 0 && types.IsDappFork(evm.StateDB.GetBlockHeight(), "evm", "ForkEVMKVHash") {
evm.StateDB.SetAbi(contractAddr.String(), abi)
}
} else { } else {
// 如果Gas不足,返回这个错误,让外部程序处理 // 如果Gas不足,返回这个错误,让外部程序处理
err = model.ErrCodeStoreOutOfGas err = model.ErrCodeStoreOutOfGas
......
...@@ -717,7 +717,7 @@ func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *mm.Memory, stack ...@@ -717,7 +717,7 @@ func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *mm.Memory, stack
// 调用合约创建逻辑 // 调用合约创建逻辑
addr := crypto.RandomContractAddress() addr := crypto.RandomContractAddress()
res, _, returnGas, suberr := evm.Create(contract, *addr, inPut, gas, "innerContract", "") res, _, returnGas, suberr := evm.Create(contract, *addr, inPut, gas, "innerContract", "", "")
// 出错时压栈0,否则压栈创建出来的合约对象的地址 // 出错时压栈0,否则压栈创建出来的合约对象的地址
if suberr != nil && suberr != model.ErrCodeStoreOutOfGas { if suberr != nil && suberr != model.ErrCodeStoreOutOfGas {
......
...@@ -165,6 +165,14 @@ func (ca *ContractAccount) LoadContract(db db.KV) { ...@@ -165,6 +165,14 @@ func (ca *ContractAccount) LoadContract(db db.KV) {
return return
} }
ca.resotreState(data) ca.resotreState(data)
// 加载 ABI (如果有的话)
if types.IsDappFork(ca.mdb.GetBlockHeight(), "evm", "ForkEVMABI") {
data, err := db.Get(ca.GetAbiKey())
if err == nil {
ca.Data.Abi = string(data)
}
}
} }
// SetCode 设置合约二进制代码 // SetCode 设置合约二进制代码
...@@ -181,6 +189,18 @@ func (ca *ContractAccount) SetCode(code []byte) { ...@@ -181,6 +189,18 @@ func (ca *ContractAccount) SetCode(code []byte) {
ca.Data.CodeHash = common.ToHash(code).Bytes() ca.Data.CodeHash = common.ToHash(code).Bytes()
} }
// SetAbi 设置合约绑定的ABI数据
func (ca *ContractAccount) SetAbi(abi string) {
if types.IsDappFork(ca.mdb.GetBlockHeight(), "evm", "ForkEVMABI") {
ca.mdb.addChange(abiChange{
baseChange: baseChange{},
account: ca.Addr,
prevabi: ca.Data.Abi,
})
ca.Data.Abi = abi
}
}
// SetCreator 设置创建者 // SetCreator 设置创建者
func (ca *ContractAccount) SetCreator(creator string) { func (ca *ContractAccount) SetCreator(creator string) {
if len(creator) == 0 { if len(creator) == 0 {
...@@ -272,6 +292,11 @@ func (ca *ContractAccount) GetDataKey() []byte { ...@@ -272,6 +292,11 @@ func (ca *ContractAccount) GetDataKey() []byte {
return []byte("mavl-" + evmtypes.ExecutorName + "-data: " + ca.Addr) return []byte("mavl-" + evmtypes.ExecutorName + "-data: " + ca.Addr)
} }
// GetAbiKey 获取Abi数据KEY,ABI数据使用单独的KEY存储
func (ca *ContractAccount) GetAbiKey() []byte {
return []byte("mavl-" + evmtypes.ExecutorName + "-abi: " + ca.Addr)
}
// GetStateKey 获取状态key // GetStateKey 获取状态key
func (ca *ContractAccount) GetStateKey() []byte { func (ca *ContractAccount) GetStateKey() []byte {
return []byte("mavl-" + evmtypes.ExecutorName + "-state: " + ca.Addr) return []byte("mavl-" + evmtypes.ExecutorName + "-state: " + ca.Addr)
......
...@@ -37,6 +37,10 @@ type EVMStateDB interface { ...@@ -37,6 +37,10 @@ type EVMStateDB interface {
SetCode(string, []byte) SetCode(string, []byte)
// GetCodeSize 获取指定地址合约代码大小 // GetCodeSize 获取指定地址合约代码大小
GetCodeSize(string) int GetCodeSize(string) int
// SetAbi 设置ABI内容
SetAbi(addr, abi string)
// GetAbi 获取ABI
GetAbi(addr string) string
// AddRefund 合约Gas奖励回馈 // AddRefund 合约Gas奖励回馈
AddRefund(uint64) AddRefund(uint64)
...@@ -74,4 +78,7 @@ type EVMStateDB interface { ...@@ -74,4 +78,7 @@ type EVMStateDB interface {
CanTransfer(sender, recipient string, amount uint64) bool CanTransfer(sender, recipient string, amount uint64) bool
// Transfer 转账交易 // Transfer 转账交易
Transfer(sender, recipient string, amount uint64) bool Transfer(sender, recipient string, amount uint64) bool
// GetBlockHeight 返回当前区块高度
GetBlockHeight() int64
} }
...@@ -123,6 +123,13 @@ type ( ...@@ -123,6 +123,13 @@ type (
prevcode, prevhash []byte prevcode, prevhash []byte
} }
// 合约ABI变更事件
abiChange struct {
baseChange
account string
prevabi string
}
// 返还金额变更事件 // 返还金额变更事件
refundChange struct { refundChange struct {
baseChange baseChange
...@@ -236,6 +243,22 @@ func (ch codeChange) getData(mdb *MemoryStateDB) (kvset []*types.KeyValue) { ...@@ -236,6 +243,22 @@ func (ch codeChange) getData(mdb *MemoryStateDB) (kvset []*types.KeyValue) {
return nil return nil
} }
func (ch abiChange) revert(mdb *MemoryStateDB) {
acc := mdb.accounts[ch.account]
if acc != nil {
acc.Data.Abi = ch.prevabi
}
}
func (ch abiChange) getData(mdb *MemoryStateDB) (kvset []*types.KeyValue) {
acc := mdb.accounts[ch.account]
if acc != nil {
kvset = append(kvset, acc.GetDataKV()...)
return kvset
}
return nil
}
func (ch storageChange) revert(mdb *MemoryStateDB) { func (ch storageChange) revert(mdb *MemoryStateDB) {
acc := mdb.accounts[ch.account] acc := mdb.accounts[ch.account]
if acc != nil { if acc != nil {
......
...@@ -193,6 +193,24 @@ func (mdb *MemoryStateDB) SetCode(addr string, code []byte) { ...@@ -193,6 +193,24 @@ func (mdb *MemoryStateDB) SetCode(addr string, code []byte) {
} }
} }
// SetAbi 设置ABI内容
func (mdb *MemoryStateDB) SetAbi(addr, abi string) {
acc := mdb.GetAccount(addr)
if acc != nil {
mdb.dataDirty[addr] = true
acc.SetAbi(abi)
}
}
// GetAbi 获取ABI
func (mdb *MemoryStateDB) GetAbi(addr string) string {
acc := mdb.GetAccount(addr)
if acc != nil {
return acc.Data.GetAbi()
}
return ""
}
// GetCodeSize 获取合约代码自身的大小 // GetCodeSize 获取合约代码自身的大小
// 对应 EXTCODESIZE 操作码 // 对应 EXTCODESIZE 操作码
func (mdb *MemoryStateDB) GetCodeSize(addr string) int { func (mdb *MemoryStateDB) GetCodeSize(addr string) int {
...@@ -686,3 +704,8 @@ func (mdb *MemoryStateDB) ResetDatas() { ...@@ -686,3 +704,8 @@ func (mdb *MemoryStateDB) ResetDatas() {
mdb.currentVer = nil mdb.currentVer = nil
mdb.snapshots = mdb.snapshots[:0] mdb.snapshots = mdb.snapshots[:0]
} }
// GetBlockHeight 返回当前区块高度
func (mdb *MemoryStateDB) GetBlockHeight() int64 {
return mdb.blockHeight
}
...@@ -17,6 +17,8 @@ message EVMContractData { ...@@ -17,6 +17,8 @@ message EVMContractData {
string addr = 4; string addr = 4;
bytes code = 5; bytes code = 5;
bytes codeHash = 6; bytes codeHash = 6;
// 绑定ABI数据 ForkEVMABI
string abi = 7;
} }
// 存放合约变化数据 // 存放合约变化数据
...@@ -41,6 +43,8 @@ message EVMContractAction { ...@@ -41,6 +43,8 @@ message EVMContractAction {
string alias = 5; string alias = 5;
// 交易备注 // 交易备注
string note = 6; string note = 6;
// 创建或调用合约时携带的ABI数据 ForkEVMABI
string abi = 7;
} }
// 合约创建/调用日志 // 合约创建/调用日志
...@@ -51,6 +55,8 @@ message ReceiptEVMContract { ...@@ -51,6 +55,8 @@ message ReceiptEVMContract {
uint64 usedGas = 4; uint64 usedGas = 4;
// 创建合约返回的代码 // 创建合约返回的代码
bytes ret = 5; bytes ret = 5;
// json格式化后的返回值
string jsonRet = 6;
} }
// 用于保存EVM只能合约中的状态数据变更 // 用于保存EVM只能合约中的状态数据变更
...@@ -104,6 +110,7 @@ message EstimateEVMGasReq { ...@@ -104,6 +110,7 @@ message EstimateEVMGasReq {
bytes code = 2; bytes code = 2;
string caller = 3; string caller = 3;
uint64 amount = 4; uint64 amount = 4;
string abi = 5;
} }
message EstimateEVMGasResp { message EstimateEVMGasResp {
uint64 gas = 1; uint64 gas = 1;
...@@ -116,4 +123,27 @@ message EvmDebugReq { ...@@ -116,4 +123,27 @@ message EvmDebugReq {
message EvmDebugResp { message EvmDebugResp {
string debugStatus = 1; string debugStatus = 1;
}
message EvmQueryAbiReq {
string address = 1;
}
message EvmQueryAbiResp {
string address = 1;
string abi = 2;
}
message EvmQueryReq {
string address = 1;
string input = 2;
string caller = 3;
}
message EvmQueryResp {
string address = 1;
string input = 2;
string caller = 3;
bytes rawData = 4;
string jsonData = 5;
} }
\ No newline at end of file
...@@ -12,7 +12,6 @@ import ( ...@@ -12,7 +12,6 @@ import (
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
ecommon "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
) )
var ( var (
...@@ -22,8 +21,6 @@ var ( ...@@ -22,8 +21,6 @@ var (
"EvmCreate": EvmCreateAction, "EvmCreate": EvmCreateAction,
"EvmCall": EvmCallAction, "EvmCall": EvmCallAction,
} }
ABICallPrefix = ecommon.FromHex("0x00000000")
) )
func init() { func init() {
...@@ -102,23 +99,6 @@ func (evm EvmType) CreateTx(action string, message json.RawMessage) (*types.Tran ...@@ -102,23 +99,6 @@ func (evm EvmType) CreateTx(action string, message json.RawMessage) (*types.Tran
} }
return createEvmTx(&param) return createEvmTx(&param)
} }
//else if action == "BindABI" {
// var param BindABI
// err := json.Unmarshal(message, &param)
// if err != nil {
// elog.Error("Create BindABI", "Error", err)
// return nil, types.ErrInvalidParam
// }
// return createBindABITx(&param)
//} else if action == "ABICall" {
// var param ABICall
// err := json.Unmarshal(message, &param)
// if err != nil {
// elog.Error("Create ABICall", "Error", err)
// return nil, types.ErrInvalidParam
// }
// return createABICallTx(&param)
//}
return nil, types.ErrNotSupport return nil, types.ErrNotSupport
} }
...@@ -127,64 +107,6 @@ func (evm *EvmType) GetLogMap() map[int64]*types.LogInfo { ...@@ -127,64 +107,6 @@ func (evm *EvmType) GetLogMap() map[int64]*types.LogInfo {
return logInfo return logInfo
} }
//func createBindABITx(param *BindABI) (*types.Transaction, error) {
// if param == nil {
// elog.Error("createBindABITx", "param", param)
// return nil, types.ErrInvalidParam
// }
//
// code := []byte(param.Data)
// code = append(BindABIPrefix, code...)
//
// action := &EVMContractAction{
// Code: code,
// Note: param.Note,
// }
//
// return createRawTx(action, param.Name)
//}
//
//func createABICallTx(param *ABICall) (*types.Transaction, error) {
// if param == nil {
// elog.Error("createABICallTx", "param", param)
// return nil, types.ErrInvalidParam
// }
//
// code := []byte(param.Data)
// code = append(ABICallPrefix, code...)
//
// action := &EVMContractAction{
// Code: code,
// Amount: param.Amount,
// }
//
// return createRawTx(action, param.Name)
//
// return nil, nil
//}
func createRawTx(action *EVMContractAction, name string) (*types.Transaction, error) {
tx := &types.Transaction{}
if len(name) == 0 {
tx = &types.Transaction{
Execer: []byte(types.ExecName(ExecutorName)),
Payload: types.Encode(action),
To: address.ExecAddress(types.ExecName(ExecutorName)),
}
} else {
tx = &types.Transaction{
Execer: []byte(types.ExecName(name)),
Payload: types.Encode(action),
To: address.ExecAddress(types.ExecName(name)),
}
}
tx, err := types.FormatTx(string(tx.Execer), tx)
if err != nil {
return nil, err
}
return tx, nil
}
func createEvmTx(param *CreateCallTx) (*types.Transaction, error) { func createEvmTx(param *CreateCallTx) (*types.Transaction, error) {
if param == nil { if param == nil {
elog.Error("createEvmTx", "param", param) elog.Error("createEvmTx", "param", param)
...@@ -194,7 +116,6 @@ func createEvmTx(param *CreateCallTx) (*types.Transaction, error) { ...@@ -194,7 +116,6 @@ func createEvmTx(param *CreateCallTx) (*types.Transaction, error) {
// 调用格式判断规则: // 调用格式判断规则:
// 十六进制格式默认使用原方式调用,其它格式,使用ABI方式调用 // 十六进制格式默认使用原方式调用,其它格式,使用ABI方式调用
// 为了方便区分,在ABI格式前加0x00000000 // 为了方便区分,在ABI格式前加0x00000000
bCode, err := common.FromHex(param.Code)
action := &EVMContractAction{ action := &EVMContractAction{
Amount: param.Amount, Amount: param.Amount,
...@@ -203,20 +124,42 @@ func createEvmTx(param *CreateCallTx) (*types.Transaction, error) { ...@@ -203,20 +124,42 @@ func createEvmTx(param *CreateCallTx) (*types.Transaction, error) {
Note: param.Note, Note: param.Note,
Alias: param.Alias, Alias: param.Alias,
} }
// Abi数据和二进制代码必须指定一个,优先判断ABI
if param.IsCreate { if len(param.Abi) > 0 {
action.Abi = strings.TrimSpace(param.Abi)
} else {
bCode, err := common.FromHex(param.Code)
if err != nil { if err != nil {
elog.Error("create evm create Tx", "param.Code", param.Code) elog.Error("create evm Tx error, code is invalid", "param.Code", param.Code)
return nil, err return nil, err
} }
action.Code = bCode action.Code = bCode
}
if param.IsCreate {
return createRawTx(action, "") return createRawTx(action, "")
}
return createRawTx(action, param.Name)
}
func createRawTx(action *EVMContractAction, name string) (*types.Transaction, error) {
tx := &types.Transaction{}
if len(name) == 0 {
tx = &types.Transaction{
Execer: []byte(types.ExecName(ExecutorName)),
Payload: types.Encode(action),
To: address.ExecAddress(types.ExecName(ExecutorName)),
}
} else { } else {
if err != nil { tx = &types.Transaction{
elog.Info("evm call data is invalid hex data, process it as abi data", "param.Code", param.Code) Execer: []byte(types.ExecName(name)),
bCode = []byte(param.Code) Payload: types.Encode(action),
bCode = append(ABICallPrefix, bCode...) To: address.ExecAddress(types.ExecName(name)),
} }
return createRawTx(action, param.Name)
} }
tx, err := types.FormatTx(string(tx.Execer), tx)
if err != nil {
return nil, err
}
return tx, nil
} }
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// source: evmcontract.proto // source: evmcontract.proto
/*
Package types is a generated protocol buffer package.
It is generated from these files:
evmcontract.proto
It has these top-level messages:
EVMContractObject
EVMContractData
EVMContractState
EVMContractAction
ReceiptEVMContract
EVMStateChangeItem
EVMContractDataCmd
EVMContractStateCmd
ReceiptEVMContractCmd
CheckEVMAddrReq
CheckEVMAddrResp
EstimateEVMGasReq
EstimateEVMGasResp
EvmDebugReq
EvmDebugResp
*/
package types package types
import proto "github.com/golang/protobuf/proto" import (
import fmt "fmt" fmt "fmt"
import math "math" math "math"
proto "github.com/golang/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
...@@ -41,17 +21,40 @@ var _ = math.Inf ...@@ -41,17 +21,40 @@ var _ = math.Inf
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// 合约对象信息 //合约对象信息
type EVMContractObject struct { type EVMContractObject struct {
Addr string `protobuf:"bytes,1,opt,name=addr" json:"addr,omitempty"` Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
Data *EVMContractData `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` Data *EVMContractData `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
State *EVMContractState `protobuf:"bytes,3,opt,name=state" json:"state,omitempty"` State *EVMContractState `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EVMContractObject) Reset() { *m = EVMContractObject{} }
func (m *EVMContractObject) String() string { return proto.CompactTextString(m) }
func (*EVMContractObject) ProtoMessage() {}
func (*EVMContractObject) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{0}
}
func (m *EVMContractObject) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EVMContractObject.Unmarshal(m, b)
}
func (m *EVMContractObject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EVMContractObject.Marshal(b, m, deterministic)
}
func (m *EVMContractObject) XXX_Merge(src proto.Message) {
xxx_messageInfo_EVMContractObject.Merge(m, src)
}
func (m *EVMContractObject) XXX_Size() int {
return xxx_messageInfo_EVMContractObject.Size(m)
}
func (m *EVMContractObject) XXX_DiscardUnknown() {
xxx_messageInfo_EVMContractObject.DiscardUnknown(m)
} }
func (m *EVMContractObject) Reset() { *m = EVMContractObject{} } var xxx_messageInfo_EVMContractObject proto.InternalMessageInfo
func (m *EVMContractObject) String() string { return proto.CompactTextString(m) }
func (*EVMContractObject) ProtoMessage() {}
func (*EVMContractObject) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *EVMContractObject) GetAddr() string { func (m *EVMContractObject) GetAddr() string {
if m != nil { if m != nil {
...@@ -76,18 +79,43 @@ func (m *EVMContractObject) GetState() *EVMContractState { ...@@ -76,18 +79,43 @@ func (m *EVMContractObject) GetState() *EVMContractState {
// 存放合约固定数据 // 存放合约固定数据
type EVMContractData struct { type EVMContractData struct {
Creator string `protobuf:"bytes,1,opt,name=creator" json:"creator,omitempty"` Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Alias string `protobuf:"bytes,3,opt,name=alias" json:"alias,omitempty"` Alias string `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
Addr string `protobuf:"bytes,4,opt,name=addr" json:"addr,omitempty"` Addr string `protobuf:"bytes,4,opt,name=addr,proto3" json:"addr,omitempty"`
Code []byte `protobuf:"bytes,5,opt,name=code,proto3" json:"code,omitempty"` Code []byte `protobuf:"bytes,5,opt,name=code,proto3" json:"code,omitempty"`
CodeHash []byte `protobuf:"bytes,6,opt,name=codeHash,proto3" json:"codeHash,omitempty"` CodeHash []byte `protobuf:"bytes,6,opt,name=codeHash,proto3" json:"codeHash,omitempty"`
// 绑定ABI数据 ForkEVMABI
Abi string `protobuf:"bytes,7,opt,name=abi,proto3" json:"abi,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EVMContractData) Reset() { *m = EVMContractData{} }
func (m *EVMContractData) String() string { return proto.CompactTextString(m) }
func (*EVMContractData) ProtoMessage() {}
func (*EVMContractData) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{1}
} }
func (m *EVMContractData) Reset() { *m = EVMContractData{} } func (m *EVMContractData) XXX_Unmarshal(b []byte) error {
func (m *EVMContractData) String() string { return proto.CompactTextString(m) } return xxx_messageInfo_EVMContractData.Unmarshal(m, b)
func (*EVMContractData) ProtoMessage() {} }
func (*EVMContractData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (m *EVMContractData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EVMContractData.Marshal(b, m, deterministic)
}
func (m *EVMContractData) XXX_Merge(src proto.Message) {
xxx_messageInfo_EVMContractData.Merge(m, src)
}
func (m *EVMContractData) XXX_Size() int {
return xxx_messageInfo_EVMContractData.Size(m)
}
func (m *EVMContractData) XXX_DiscardUnknown() {
xxx_messageInfo_EVMContractData.DiscardUnknown(m)
}
var xxx_messageInfo_EVMContractData proto.InternalMessageInfo
func (m *EVMContractData) GetCreator() string { func (m *EVMContractData) GetCreator() string {
if m != nil { if m != nil {
...@@ -131,18 +159,48 @@ func (m *EVMContractData) GetCodeHash() []byte { ...@@ -131,18 +159,48 @@ func (m *EVMContractData) GetCodeHash() []byte {
return nil return nil
} }
func (m *EVMContractData) GetAbi() string {
if m != nil {
return m.Abi
}
return ""
}
// 存放合约变化数据 // 存放合约变化数据
type EVMContractState struct { type EVMContractState struct {
Nonce uint64 `protobuf:"varint,1,opt,name=nonce" json:"nonce,omitempty"` Nonce uint64 `protobuf:"varint,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
Suicided bool `protobuf:"varint,2,opt,name=suicided" json:"suicided,omitempty"` Suicided bool `protobuf:"varint,2,opt,name=suicided,proto3" json:"suicided,omitempty"`
StorageHash []byte `protobuf:"bytes,3,opt,name=storageHash,proto3" json:"storageHash,omitempty"` StorageHash []byte `protobuf:"bytes,3,opt,name=storageHash,proto3" json:"storageHash,omitempty"`
Storage map[string][]byte `protobuf:"bytes,4,rep,name=storage" json:"storage,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"` Storage map[string][]byte `protobuf:"bytes,4,rep,name=storage,proto3" json:"storage,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *EVMContractState) Reset() { *m = EVMContractState{} } func (m *EVMContractState) Reset() { *m = EVMContractState{} }
func (m *EVMContractState) String() string { return proto.CompactTextString(m) } func (m *EVMContractState) String() string { return proto.CompactTextString(m) }
func (*EVMContractState) ProtoMessage() {} func (*EVMContractState) ProtoMessage() {}
func (*EVMContractState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } func (*EVMContractState) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{2}
}
func (m *EVMContractState) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EVMContractState.Unmarshal(m, b)
}
func (m *EVMContractState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EVMContractState.Marshal(b, m, deterministic)
}
func (m *EVMContractState) XXX_Merge(src proto.Message) {
xxx_messageInfo_EVMContractState.Merge(m, src)
}
func (m *EVMContractState) XXX_Size() int {
return xxx_messageInfo_EVMContractState.Size(m)
}
func (m *EVMContractState) XXX_DiscardUnknown() {
xxx_messageInfo_EVMContractState.DiscardUnknown(m)
}
var xxx_messageInfo_EVMContractState proto.InternalMessageInfo
func (m *EVMContractState) GetNonce() uint64 { func (m *EVMContractState) GetNonce() uint64 {
if m != nil { if m != nil {
...@@ -175,23 +233,48 @@ func (m *EVMContractState) GetStorage() map[string][]byte { ...@@ -175,23 +233,48 @@ func (m *EVMContractState) GetStorage() map[string][]byte {
// 创建/调用合约的请求结构 // 创建/调用合约的请求结构
type EVMContractAction struct { type EVMContractAction struct {
// 转账金额 // 转账金额
Amount uint64 `protobuf:"varint,1,opt,name=amount" json:"amount,omitempty"` Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"`
// 消耗限制,默认为Transaction.Fee // 消耗限制,默认为Transaction.Fee
GasLimit uint64 `protobuf:"varint,2,opt,name=gasLimit" json:"gasLimit,omitempty"` GasLimit uint64 `protobuf:"varint,2,opt,name=gasLimit,proto3" json:"gasLimit,omitempty"`
// gas价格,默认为1 // gas价格,默认为1
GasPrice uint32 `protobuf:"varint,3,opt,name=gasPrice" json:"gasPrice,omitempty"` GasPrice uint32 `protobuf:"varint,3,opt,name=gasPrice,proto3" json:"gasPrice,omitempty"`
// 合约数据 // 合约数据
Code []byte `protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"` Code []byte `protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"`
// 合约别名,方便识别 // 合约别名,方便识别
Alias string `protobuf:"bytes,5,opt,name=alias" json:"alias,omitempty"` Alias string `protobuf:"bytes,5,opt,name=alias,proto3" json:"alias,omitempty"`
// 交易备注 // 交易备注
Note string `protobuf:"bytes,6,opt,name=note" json:"note,omitempty"` Note string `protobuf:"bytes,6,opt,name=note,proto3" json:"note,omitempty"`
// 创建或调用合约时携带的ABI数据 ForkEVMABI
Abi string `protobuf:"bytes,7,opt,name=abi,proto3" json:"abi,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *EVMContractAction) Reset() { *m = EVMContractAction{} } func (m *EVMContractAction) Reset() { *m = EVMContractAction{} }
func (m *EVMContractAction) String() string { return proto.CompactTextString(m) } func (m *EVMContractAction) String() string { return proto.CompactTextString(m) }
func (*EVMContractAction) ProtoMessage() {} func (*EVMContractAction) ProtoMessage() {}
func (*EVMContractAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } func (*EVMContractAction) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{3}
}
func (m *EVMContractAction) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EVMContractAction.Unmarshal(m, b)
}
func (m *EVMContractAction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EVMContractAction.Marshal(b, m, deterministic)
}
func (m *EVMContractAction) XXX_Merge(src proto.Message) {
xxx_messageInfo_EVMContractAction.Merge(m, src)
}
func (m *EVMContractAction) XXX_Size() int {
return xxx_messageInfo_EVMContractAction.Size(m)
}
func (m *EVMContractAction) XXX_DiscardUnknown() {
xxx_messageInfo_EVMContractAction.DiscardUnknown(m)
}
var xxx_messageInfo_EVMContractAction proto.InternalMessageInfo
func (m *EVMContractAction) GetAmount() uint64 { func (m *EVMContractAction) GetAmount() uint64 {
if m != nil { if m != nil {
...@@ -235,20 +318,52 @@ func (m *EVMContractAction) GetNote() string { ...@@ -235,20 +318,52 @@ func (m *EVMContractAction) GetNote() string {
return "" return ""
} }
func (m *EVMContractAction) GetAbi() string {
if m != nil {
return m.Abi
}
return ""
}
// 合约创建/调用日志 // 合约创建/调用日志
type ReceiptEVMContract struct { type ReceiptEVMContract struct {
Caller string `protobuf:"bytes,1,opt,name=caller" json:"caller,omitempty"` Caller string `protobuf:"bytes,1,opt,name=caller,proto3" json:"caller,omitempty"`
ContractName string `protobuf:"bytes,2,opt,name=contractName" json:"contractName,omitempty"` ContractName string `protobuf:"bytes,2,opt,name=contractName,proto3" json:"contractName,omitempty"`
ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr" json:"contractAddr,omitempty"` ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"`
UsedGas uint64 `protobuf:"varint,4,opt,name=usedGas" json:"usedGas,omitempty"` UsedGas uint64 `protobuf:"varint,4,opt,name=usedGas,proto3" json:"usedGas,omitempty"`
// 创建合约返回的代码 // 创建合约返回的代码
Ret []byte `protobuf:"bytes,5,opt,name=ret,proto3" json:"ret,omitempty"` Ret []byte `protobuf:"bytes,5,opt,name=ret,proto3" json:"ret,omitempty"`
// json格式化后的返回值
JsonRet string `protobuf:"bytes,6,opt,name=jsonRet,proto3" json:"jsonRet,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReceiptEVMContract) Reset() { *m = ReceiptEVMContract{} }
func (m *ReceiptEVMContract) String() string { return proto.CompactTextString(m) }
func (*ReceiptEVMContract) ProtoMessage() {}
func (*ReceiptEVMContract) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{4}
}
func (m *ReceiptEVMContract) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReceiptEVMContract.Unmarshal(m, b)
}
func (m *ReceiptEVMContract) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReceiptEVMContract.Marshal(b, m, deterministic)
}
func (m *ReceiptEVMContract) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReceiptEVMContract.Merge(m, src)
}
func (m *ReceiptEVMContract) XXX_Size() int {
return xxx_messageInfo_ReceiptEVMContract.Size(m)
}
func (m *ReceiptEVMContract) XXX_DiscardUnknown() {
xxx_messageInfo_ReceiptEVMContract.DiscardUnknown(m)
} }
func (m *ReceiptEVMContract) Reset() { *m = ReceiptEVMContract{} } var xxx_messageInfo_ReceiptEVMContract proto.InternalMessageInfo
func (m *ReceiptEVMContract) String() string { return proto.CompactTextString(m) }
func (*ReceiptEVMContract) ProtoMessage() {}
func (*ReceiptEVMContract) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *ReceiptEVMContract) GetCaller() string { func (m *ReceiptEVMContract) GetCaller() string {
if m != nil { if m != nil {
...@@ -285,17 +400,47 @@ func (m *ReceiptEVMContract) GetRet() []byte { ...@@ -285,17 +400,47 @@ func (m *ReceiptEVMContract) GetRet() []byte {
return nil return nil
} }
func (m *ReceiptEVMContract) GetJsonRet() string {
if m != nil {
return m.JsonRet
}
return ""
}
// 用于保存EVM只能合约中的状态数据变更 // 用于保存EVM只能合约中的状态数据变更
type EVMStateChangeItem struct { type EVMStateChangeItem struct {
Key string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
PreValue []byte `protobuf:"bytes,2,opt,name=preValue,proto3" json:"preValue,omitempty"` PreValue []byte `protobuf:"bytes,2,opt,name=preValue,proto3" json:"preValue,omitempty"`
CurrentValue []byte `protobuf:"bytes,3,opt,name=currentValue,proto3" json:"currentValue,omitempty"` CurrentValue []byte `protobuf:"bytes,3,opt,name=currentValue,proto3" json:"currentValue,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EVMStateChangeItem) Reset() { *m = EVMStateChangeItem{} }
func (m *EVMStateChangeItem) String() string { return proto.CompactTextString(m) }
func (*EVMStateChangeItem) ProtoMessage() {}
func (*EVMStateChangeItem) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{5}
}
func (m *EVMStateChangeItem) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EVMStateChangeItem.Unmarshal(m, b)
}
func (m *EVMStateChangeItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EVMStateChangeItem.Marshal(b, m, deterministic)
}
func (m *EVMStateChangeItem) XXX_Merge(src proto.Message) {
xxx_messageInfo_EVMStateChangeItem.Merge(m, src)
}
func (m *EVMStateChangeItem) XXX_Size() int {
return xxx_messageInfo_EVMStateChangeItem.Size(m)
}
func (m *EVMStateChangeItem) XXX_DiscardUnknown() {
xxx_messageInfo_EVMStateChangeItem.DiscardUnknown(m)
} }
func (m *EVMStateChangeItem) Reset() { *m = EVMStateChangeItem{} } var xxx_messageInfo_EVMStateChangeItem proto.InternalMessageInfo
func (m *EVMStateChangeItem) String() string { return proto.CompactTextString(m) }
func (*EVMStateChangeItem) ProtoMessage() {}
func (*EVMStateChangeItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *EVMStateChangeItem) GetKey() string { func (m *EVMStateChangeItem) GetKey() string {
if m != nil { if m != nil {
...@@ -320,18 +465,41 @@ func (m *EVMStateChangeItem) GetCurrentValue() []byte { ...@@ -320,18 +465,41 @@ func (m *EVMStateChangeItem) GetCurrentValue() []byte {
// 存放合约固定数据 // 存放合约固定数据
type EVMContractDataCmd struct { type EVMContractDataCmd struct {
Creator string `protobuf:"bytes,1,opt,name=creator" json:"creator,omitempty"` Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Alias string `protobuf:"bytes,3,opt,name=alias" json:"alias,omitempty"` Alias string `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
Addr string `protobuf:"bytes,4,opt,name=addr" json:"addr,omitempty"` Addr string `protobuf:"bytes,4,opt,name=addr,proto3" json:"addr,omitempty"`
Code string `protobuf:"bytes,5,opt,name=code" json:"code,omitempty"` Code string `protobuf:"bytes,5,opt,name=code,proto3" json:"code,omitempty"`
CodeHash string `protobuf:"bytes,6,opt,name=codeHash" json:"codeHash,omitempty"` CodeHash string `protobuf:"bytes,6,opt,name=codeHash,proto3" json:"codeHash,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EVMContractDataCmd) Reset() { *m = EVMContractDataCmd{} }
func (m *EVMContractDataCmd) String() string { return proto.CompactTextString(m) }
func (*EVMContractDataCmd) ProtoMessage() {}
func (*EVMContractDataCmd) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{6}
}
func (m *EVMContractDataCmd) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EVMContractDataCmd.Unmarshal(m, b)
}
func (m *EVMContractDataCmd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EVMContractDataCmd.Marshal(b, m, deterministic)
}
func (m *EVMContractDataCmd) XXX_Merge(src proto.Message) {
xxx_messageInfo_EVMContractDataCmd.Merge(m, src)
}
func (m *EVMContractDataCmd) XXX_Size() int {
return xxx_messageInfo_EVMContractDataCmd.Size(m)
}
func (m *EVMContractDataCmd) XXX_DiscardUnknown() {
xxx_messageInfo_EVMContractDataCmd.DiscardUnknown(m)
} }
func (m *EVMContractDataCmd) Reset() { *m = EVMContractDataCmd{} } var xxx_messageInfo_EVMContractDataCmd proto.InternalMessageInfo
func (m *EVMContractDataCmd) String() string { return proto.CompactTextString(m) }
func (*EVMContractDataCmd) ProtoMessage() {}
func (*EVMContractDataCmd) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *EVMContractDataCmd) GetCreator() string { func (m *EVMContractDataCmd) GetCreator() string {
if m != nil { if m != nil {
...@@ -377,16 +545,39 @@ func (m *EVMContractDataCmd) GetCodeHash() string { ...@@ -377,16 +545,39 @@ func (m *EVMContractDataCmd) GetCodeHash() string {
// 存放合约变化数据 // 存放合约变化数据
type EVMContractStateCmd struct { type EVMContractStateCmd struct {
Nonce uint64 `protobuf:"varint,1,opt,name=nonce" json:"nonce,omitempty"` Nonce uint64 `protobuf:"varint,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
Suicided bool `protobuf:"varint,2,opt,name=suicided" json:"suicided,omitempty"` Suicided bool `protobuf:"varint,2,opt,name=suicided,proto3" json:"suicided,omitempty"`
StorageHash string `protobuf:"bytes,3,opt,name=storageHash" json:"storageHash,omitempty"` StorageHash string `protobuf:"bytes,3,opt,name=storageHash,proto3" json:"storageHash,omitempty"`
Storage map[string]string `protobuf:"bytes,4,rep,name=storage" json:"storage,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` Storage map[string]string `protobuf:"bytes,4,rep,name=storage,proto3" json:"storage,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *EVMContractStateCmd) Reset() { *m = EVMContractStateCmd{} } func (m *EVMContractStateCmd) Reset() { *m = EVMContractStateCmd{} }
func (m *EVMContractStateCmd) String() string { return proto.CompactTextString(m) } func (m *EVMContractStateCmd) String() string { return proto.CompactTextString(m) }
func (*EVMContractStateCmd) ProtoMessage() {} func (*EVMContractStateCmd) ProtoMessage() {}
func (*EVMContractStateCmd) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (*EVMContractStateCmd) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{7}
}
func (m *EVMContractStateCmd) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EVMContractStateCmd.Unmarshal(m, b)
}
func (m *EVMContractStateCmd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EVMContractStateCmd.Marshal(b, m, deterministic)
}
func (m *EVMContractStateCmd) XXX_Merge(src proto.Message) {
xxx_messageInfo_EVMContractStateCmd.Merge(m, src)
}
func (m *EVMContractStateCmd) XXX_Size() int {
return xxx_messageInfo_EVMContractStateCmd.Size(m)
}
func (m *EVMContractStateCmd) XXX_DiscardUnknown() {
xxx_messageInfo_EVMContractStateCmd.DiscardUnknown(m)
}
var xxx_messageInfo_EVMContractStateCmd proto.InternalMessageInfo
func (m *EVMContractStateCmd) GetNonce() uint64 { func (m *EVMContractStateCmd) GetNonce() uint64 {
if m != nil { if m != nil {
...@@ -418,19 +609,42 @@ func (m *EVMContractStateCmd) GetStorage() map[string]string { ...@@ -418,19 +609,42 @@ func (m *EVMContractStateCmd) GetStorage() map[string]string {
// 合约创建/调用日志 // 合约创建/调用日志
type ReceiptEVMContractCmd struct { type ReceiptEVMContractCmd struct {
Caller string `protobuf:"bytes,1,opt,name=caller" json:"caller,omitempty"` Caller string `protobuf:"bytes,1,opt,name=caller,proto3" json:"caller,omitempty"`
// 合约创建时才会返回此内容 // 合约创建时才会返回此内容
ContractName string `protobuf:"bytes,2,opt,name=contractName" json:"contractName,omitempty"` ContractName string `protobuf:"bytes,2,opt,name=contractName,proto3" json:"contractName,omitempty"`
ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr" json:"contractAddr,omitempty"` ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"`
UsedGas uint64 `protobuf:"varint,4,opt,name=usedGas" json:"usedGas,omitempty"` UsedGas uint64 `protobuf:"varint,4,opt,name=usedGas,proto3" json:"usedGas,omitempty"`
// 创建合约返回的代码 // 创建合约返回的代码
Ret string `protobuf:"bytes,5,opt,name=ret" json:"ret,omitempty"` Ret string `protobuf:"bytes,5,opt,name=ret,proto3" json:"ret,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *ReceiptEVMContractCmd) Reset() { *m = ReceiptEVMContractCmd{} } func (m *ReceiptEVMContractCmd) Reset() { *m = ReceiptEVMContractCmd{} }
func (m *ReceiptEVMContractCmd) String() string { return proto.CompactTextString(m) } func (m *ReceiptEVMContractCmd) String() string { return proto.CompactTextString(m) }
func (*ReceiptEVMContractCmd) ProtoMessage() {} func (*ReceiptEVMContractCmd) ProtoMessage() {}
func (*ReceiptEVMContractCmd) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } func (*ReceiptEVMContractCmd) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{8}
}
func (m *ReceiptEVMContractCmd) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReceiptEVMContractCmd.Unmarshal(m, b)
}
func (m *ReceiptEVMContractCmd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReceiptEVMContractCmd.Marshal(b, m, deterministic)
}
func (m *ReceiptEVMContractCmd) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReceiptEVMContractCmd.Merge(m, src)
}
func (m *ReceiptEVMContractCmd) XXX_Size() int {
return xxx_messageInfo_ReceiptEVMContractCmd.Size(m)
}
func (m *ReceiptEVMContractCmd) XXX_DiscardUnknown() {
xxx_messageInfo_ReceiptEVMContractCmd.DiscardUnknown(m)
}
var xxx_messageInfo_ReceiptEVMContractCmd proto.InternalMessageInfo
func (m *ReceiptEVMContractCmd) GetCaller() string { func (m *ReceiptEVMContractCmd) GetCaller() string {
if m != nil { if m != nil {
...@@ -468,13 +682,36 @@ func (m *ReceiptEVMContractCmd) GetRet() string { ...@@ -468,13 +682,36 @@ func (m *ReceiptEVMContractCmd) GetRet() string {
} }
type CheckEVMAddrReq struct { type CheckEVMAddrReq struct {
Addr string `protobuf:"bytes,1,opt,name=addr" json:"addr,omitempty"` Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *CheckEVMAddrReq) Reset() { *m = CheckEVMAddrReq{} } func (m *CheckEVMAddrReq) Reset() { *m = CheckEVMAddrReq{} }
func (m *CheckEVMAddrReq) String() string { return proto.CompactTextString(m) } func (m *CheckEVMAddrReq) String() string { return proto.CompactTextString(m) }
func (*CheckEVMAddrReq) ProtoMessage() {} func (*CheckEVMAddrReq) ProtoMessage() {}
func (*CheckEVMAddrReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } func (*CheckEVMAddrReq) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{9}
}
func (m *CheckEVMAddrReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CheckEVMAddrReq.Unmarshal(m, b)
}
func (m *CheckEVMAddrReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CheckEVMAddrReq.Marshal(b, m, deterministic)
}
func (m *CheckEVMAddrReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_CheckEVMAddrReq.Merge(m, src)
}
func (m *CheckEVMAddrReq) XXX_Size() int {
return xxx_messageInfo_CheckEVMAddrReq.Size(m)
}
func (m *CheckEVMAddrReq) XXX_DiscardUnknown() {
xxx_messageInfo_CheckEVMAddrReq.DiscardUnknown(m)
}
var xxx_messageInfo_CheckEVMAddrReq proto.InternalMessageInfo
func (m *CheckEVMAddrReq) GetAddr() string { func (m *CheckEVMAddrReq) GetAddr() string {
if m != nil { if m != nil {
...@@ -484,16 +721,39 @@ func (m *CheckEVMAddrReq) GetAddr() string { ...@@ -484,16 +721,39 @@ func (m *CheckEVMAddrReq) GetAddr() string {
} }
type CheckEVMAddrResp struct { type CheckEVMAddrResp struct {
Contract bool `protobuf:"varint,1,opt,name=contract" json:"contract,omitempty"` Contract bool `protobuf:"varint,1,opt,name=contract,proto3" json:"contract,omitempty"`
ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr" json:"contractAddr,omitempty"` ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"`
ContractName string `protobuf:"bytes,3,opt,name=contractName" json:"contractName,omitempty"` ContractName string `protobuf:"bytes,3,opt,name=contractName,proto3" json:"contractName,omitempty"`
AliasName string `protobuf:"bytes,4,opt,name=aliasName" json:"aliasName,omitempty"` AliasName string `protobuf:"bytes,4,opt,name=aliasName,proto3" json:"aliasName,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *CheckEVMAddrResp) Reset() { *m = CheckEVMAddrResp{} } func (m *CheckEVMAddrResp) Reset() { *m = CheckEVMAddrResp{} }
func (m *CheckEVMAddrResp) String() string { return proto.CompactTextString(m) } func (m *CheckEVMAddrResp) String() string { return proto.CompactTextString(m) }
func (*CheckEVMAddrResp) ProtoMessage() {} func (*CheckEVMAddrResp) ProtoMessage() {}
func (*CheckEVMAddrResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } func (*CheckEVMAddrResp) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{10}
}
func (m *CheckEVMAddrResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CheckEVMAddrResp.Unmarshal(m, b)
}
func (m *CheckEVMAddrResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CheckEVMAddrResp.Marshal(b, m, deterministic)
}
func (m *CheckEVMAddrResp) XXX_Merge(src proto.Message) {
xxx_messageInfo_CheckEVMAddrResp.Merge(m, src)
}
func (m *CheckEVMAddrResp) XXX_Size() int {
return xxx_messageInfo_CheckEVMAddrResp.Size(m)
}
func (m *CheckEVMAddrResp) XXX_DiscardUnknown() {
xxx_messageInfo_CheckEVMAddrResp.DiscardUnknown(m)
}
var xxx_messageInfo_CheckEVMAddrResp proto.InternalMessageInfo
func (m *CheckEVMAddrResp) GetContract() bool { func (m *CheckEVMAddrResp) GetContract() bool {
if m != nil { if m != nil {
...@@ -524,16 +784,40 @@ func (m *CheckEVMAddrResp) GetAliasName() string { ...@@ -524,16 +784,40 @@ func (m *CheckEVMAddrResp) GetAliasName() string {
} }
type EstimateEVMGasReq struct { type EstimateEVMGasReq struct {
To string `protobuf:"bytes,1,opt,name=to" json:"to,omitempty"` To string `protobuf:"bytes,1,opt,name=to,proto3" json:"to,omitempty"`
Code []byte `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` Code []byte `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
Caller string `protobuf:"bytes,3,opt,name=caller" json:"caller,omitempty"` Caller string `protobuf:"bytes,3,opt,name=caller,proto3" json:"caller,omitempty"`
Amount uint64 `protobuf:"varint,4,opt,name=amount" json:"amount,omitempty"` Amount uint64 `protobuf:"varint,4,opt,name=amount,proto3" json:"amount,omitempty"`
Abi string `protobuf:"bytes,5,opt,name=abi,proto3" json:"abi,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EstimateEVMGasReq) Reset() { *m = EstimateEVMGasReq{} }
func (m *EstimateEVMGasReq) String() string { return proto.CompactTextString(m) }
func (*EstimateEVMGasReq) ProtoMessage() {}
func (*EstimateEVMGasReq) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{11}
}
func (m *EstimateEVMGasReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EstimateEVMGasReq.Unmarshal(m, b)
}
func (m *EstimateEVMGasReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EstimateEVMGasReq.Marshal(b, m, deterministic)
}
func (m *EstimateEVMGasReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_EstimateEVMGasReq.Merge(m, src)
}
func (m *EstimateEVMGasReq) XXX_Size() int {
return xxx_messageInfo_EstimateEVMGasReq.Size(m)
}
func (m *EstimateEVMGasReq) XXX_DiscardUnknown() {
xxx_messageInfo_EstimateEVMGasReq.DiscardUnknown(m)
} }
func (m *EstimateEVMGasReq) Reset() { *m = EstimateEVMGasReq{} } var xxx_messageInfo_EstimateEVMGasReq proto.InternalMessageInfo
func (m *EstimateEVMGasReq) String() string { return proto.CompactTextString(m) }
func (*EstimateEVMGasReq) ProtoMessage() {}
func (*EstimateEVMGasReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
func (m *EstimateEVMGasReq) GetTo() string { func (m *EstimateEVMGasReq) GetTo() string {
if m != nil { if m != nil {
...@@ -563,14 +847,44 @@ func (m *EstimateEVMGasReq) GetAmount() uint64 { ...@@ -563,14 +847,44 @@ func (m *EstimateEVMGasReq) GetAmount() uint64 {
return 0 return 0
} }
func (m *EstimateEVMGasReq) GetAbi() string {
if m != nil {
return m.Abi
}
return ""
}
type EstimateEVMGasResp struct { type EstimateEVMGasResp struct {
Gas uint64 `protobuf:"varint,1,opt,name=gas" json:"gas,omitempty"` Gas uint64 `protobuf:"varint,1,opt,name=gas,proto3" json:"gas,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EstimateEVMGasResp) Reset() { *m = EstimateEVMGasResp{} }
func (m *EstimateEVMGasResp) String() string { return proto.CompactTextString(m) }
func (*EstimateEVMGasResp) ProtoMessage() {}
func (*EstimateEVMGasResp) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{12}
}
func (m *EstimateEVMGasResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EstimateEVMGasResp.Unmarshal(m, b)
}
func (m *EstimateEVMGasResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EstimateEVMGasResp.Marshal(b, m, deterministic)
}
func (m *EstimateEVMGasResp) XXX_Merge(src proto.Message) {
xxx_messageInfo_EstimateEVMGasResp.Merge(m, src)
}
func (m *EstimateEVMGasResp) XXX_Size() int {
return xxx_messageInfo_EstimateEVMGasResp.Size(m)
}
func (m *EstimateEVMGasResp) XXX_DiscardUnknown() {
xxx_messageInfo_EstimateEVMGasResp.DiscardUnknown(m)
} }
func (m *EstimateEVMGasResp) Reset() { *m = EstimateEVMGasResp{} } var xxx_messageInfo_EstimateEVMGasResp proto.InternalMessageInfo
func (m *EstimateEVMGasResp) String() string { return proto.CompactTextString(m) }
func (*EstimateEVMGasResp) ProtoMessage() {}
func (*EstimateEVMGasResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (m *EstimateEVMGasResp) GetGas() uint64 { func (m *EstimateEVMGasResp) GetGas() uint64 {
if m != nil { if m != nil {
...@@ -581,13 +895,36 @@ func (m *EstimateEVMGasResp) GetGas() uint64 { ...@@ -581,13 +895,36 @@ func (m *EstimateEVMGasResp) GetGas() uint64 {
type EvmDebugReq struct { type EvmDebugReq struct {
// 0 query, 1 set, -1 clear // 0 query, 1 set, -1 clear
Optype int32 `protobuf:"varint,1,opt,name=optype" json:"optype,omitempty"` Optype int32 `protobuf:"varint,1,opt,name=optype,proto3" json:"optype,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EvmDebugReq) Reset() { *m = EvmDebugReq{} }
func (m *EvmDebugReq) String() string { return proto.CompactTextString(m) }
func (*EvmDebugReq) ProtoMessage() {}
func (*EvmDebugReq) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{13}
}
func (m *EvmDebugReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmDebugReq.Unmarshal(m, b)
}
func (m *EvmDebugReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmDebugReq.Marshal(b, m, deterministic)
}
func (m *EvmDebugReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmDebugReq.Merge(m, src)
}
func (m *EvmDebugReq) XXX_Size() int {
return xxx_messageInfo_EvmDebugReq.Size(m)
}
func (m *EvmDebugReq) XXX_DiscardUnknown() {
xxx_messageInfo_EvmDebugReq.DiscardUnknown(m)
} }
func (m *EvmDebugReq) Reset() { *m = EvmDebugReq{} } var xxx_messageInfo_EvmDebugReq proto.InternalMessageInfo
func (m *EvmDebugReq) String() string { return proto.CompactTextString(m) }
func (*EvmDebugReq) ProtoMessage() {}
func (*EvmDebugReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (m *EvmDebugReq) GetOptype() int32 { func (m *EvmDebugReq) GetOptype() int32 {
if m != nil { if m != nil {
...@@ -597,13 +934,36 @@ func (m *EvmDebugReq) GetOptype() int32 { ...@@ -597,13 +934,36 @@ func (m *EvmDebugReq) GetOptype() int32 {
} }
type EvmDebugResp struct { type EvmDebugResp struct {
DebugStatus string `protobuf:"bytes,1,opt,name=debugStatus" json:"debugStatus,omitempty"` DebugStatus string `protobuf:"bytes,1,opt,name=debugStatus,proto3" json:"debugStatus,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *EvmDebugResp) Reset() { *m = EvmDebugResp{} } func (m *EvmDebugResp) Reset() { *m = EvmDebugResp{} }
func (m *EvmDebugResp) String() string { return proto.CompactTextString(m) } func (m *EvmDebugResp) String() string { return proto.CompactTextString(m) }
func (*EvmDebugResp) ProtoMessage() {} func (*EvmDebugResp) ProtoMessage() {}
func (*EvmDebugResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } func (*EvmDebugResp) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{14}
}
func (m *EvmDebugResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmDebugResp.Unmarshal(m, b)
}
func (m *EvmDebugResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmDebugResp.Marshal(b, m, deterministic)
}
func (m *EvmDebugResp) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmDebugResp.Merge(m, src)
}
func (m *EvmDebugResp) XXX_Size() int {
return xxx_messageInfo_EvmDebugResp.Size(m)
}
func (m *EvmDebugResp) XXX_DiscardUnknown() {
xxx_messageInfo_EvmDebugResp.DiscardUnknown(m)
}
var xxx_messageInfo_EvmDebugResp proto.InternalMessageInfo
func (m *EvmDebugResp) GetDebugStatus() string { func (m *EvmDebugResp) GetDebugStatus() string {
if m != nil { if m != nil {
...@@ -612,15 +972,229 @@ func (m *EvmDebugResp) GetDebugStatus() string { ...@@ -612,15 +972,229 @@ func (m *EvmDebugResp) GetDebugStatus() string {
return "" return ""
} }
type EvmQueryAbiReq struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EvmQueryAbiReq) Reset() { *m = EvmQueryAbiReq{} }
func (m *EvmQueryAbiReq) String() string { return proto.CompactTextString(m) }
func (*EvmQueryAbiReq) ProtoMessage() {}
func (*EvmQueryAbiReq) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{15}
}
func (m *EvmQueryAbiReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmQueryAbiReq.Unmarshal(m, b)
}
func (m *EvmQueryAbiReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmQueryAbiReq.Marshal(b, m, deterministic)
}
func (m *EvmQueryAbiReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmQueryAbiReq.Merge(m, src)
}
func (m *EvmQueryAbiReq) XXX_Size() int {
return xxx_messageInfo_EvmQueryAbiReq.Size(m)
}
func (m *EvmQueryAbiReq) XXX_DiscardUnknown() {
xxx_messageInfo_EvmQueryAbiReq.DiscardUnknown(m)
}
var xxx_messageInfo_EvmQueryAbiReq proto.InternalMessageInfo
func (m *EvmQueryAbiReq) GetAddress() string {
if m != nil {
return m.Address
}
return ""
}
type EvmQueryAbiResp struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Abi string `protobuf:"bytes,2,opt,name=abi,proto3" json:"abi,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EvmQueryAbiResp) Reset() { *m = EvmQueryAbiResp{} }
func (m *EvmQueryAbiResp) String() string { return proto.CompactTextString(m) }
func (*EvmQueryAbiResp) ProtoMessage() {}
func (*EvmQueryAbiResp) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{16}
}
func (m *EvmQueryAbiResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmQueryAbiResp.Unmarshal(m, b)
}
func (m *EvmQueryAbiResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmQueryAbiResp.Marshal(b, m, deterministic)
}
func (m *EvmQueryAbiResp) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmQueryAbiResp.Merge(m, src)
}
func (m *EvmQueryAbiResp) XXX_Size() int {
return xxx_messageInfo_EvmQueryAbiResp.Size(m)
}
func (m *EvmQueryAbiResp) XXX_DiscardUnknown() {
xxx_messageInfo_EvmQueryAbiResp.DiscardUnknown(m)
}
var xxx_messageInfo_EvmQueryAbiResp proto.InternalMessageInfo
func (m *EvmQueryAbiResp) GetAddress() string {
if m != nil {
return m.Address
}
return ""
}
func (m *EvmQueryAbiResp) GetAbi() string {
if m != nil {
return m.Abi
}
return ""
}
type EvmQueryReq struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Input string `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"`
Caller string `protobuf:"bytes,3,opt,name=caller,proto3" json:"caller,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EvmQueryReq) Reset() { *m = EvmQueryReq{} }
func (m *EvmQueryReq) String() string { return proto.CompactTextString(m) }
func (*EvmQueryReq) ProtoMessage() {}
func (*EvmQueryReq) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{17}
}
func (m *EvmQueryReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmQueryReq.Unmarshal(m, b)
}
func (m *EvmQueryReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmQueryReq.Marshal(b, m, deterministic)
}
func (m *EvmQueryReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmQueryReq.Merge(m, src)
}
func (m *EvmQueryReq) XXX_Size() int {
return xxx_messageInfo_EvmQueryReq.Size(m)
}
func (m *EvmQueryReq) XXX_DiscardUnknown() {
xxx_messageInfo_EvmQueryReq.DiscardUnknown(m)
}
var xxx_messageInfo_EvmQueryReq proto.InternalMessageInfo
func (m *EvmQueryReq) GetAddress() string {
if m != nil {
return m.Address
}
return ""
}
func (m *EvmQueryReq) GetInput() string {
if m != nil {
return m.Input
}
return ""
}
func (m *EvmQueryReq) GetCaller() string {
if m != nil {
return m.Caller
}
return ""
}
type EvmQueryResp struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Input string `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"`
Caller string `protobuf:"bytes,3,opt,name=caller,proto3" json:"caller,omitempty"`
RawData []byte `protobuf:"bytes,4,opt,name=rawData,proto3" json:"rawData,omitempty"`
JsonData string `protobuf:"bytes,5,opt,name=jsonData,proto3" json:"jsonData,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EvmQueryResp) Reset() { *m = EvmQueryResp{} }
func (m *EvmQueryResp) String() string { return proto.CompactTextString(m) }
func (*EvmQueryResp) ProtoMessage() {}
func (*EvmQueryResp) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{18}
}
func (m *EvmQueryResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmQueryResp.Unmarshal(m, b)
}
func (m *EvmQueryResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmQueryResp.Marshal(b, m, deterministic)
}
func (m *EvmQueryResp) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmQueryResp.Merge(m, src)
}
func (m *EvmQueryResp) XXX_Size() int {
return xxx_messageInfo_EvmQueryResp.Size(m)
}
func (m *EvmQueryResp) XXX_DiscardUnknown() {
xxx_messageInfo_EvmQueryResp.DiscardUnknown(m)
}
var xxx_messageInfo_EvmQueryResp proto.InternalMessageInfo
func (m *EvmQueryResp) GetAddress() string {
if m != nil {
return m.Address
}
return ""
}
func (m *EvmQueryResp) GetInput() string {
if m != nil {
return m.Input
}
return ""
}
func (m *EvmQueryResp) GetCaller() string {
if m != nil {
return m.Caller
}
return ""
}
func (m *EvmQueryResp) GetRawData() []byte {
if m != nil {
return m.RawData
}
return nil
}
func (m *EvmQueryResp) GetJsonData() string {
if m != nil {
return m.JsonData
}
return ""
}
func init() { func init() {
proto.RegisterType((*EVMContractObject)(nil), "types.EVMContractObject") proto.RegisterType((*EVMContractObject)(nil), "types.EVMContractObject")
proto.RegisterType((*EVMContractData)(nil), "types.EVMContractData") proto.RegisterType((*EVMContractData)(nil), "types.EVMContractData")
proto.RegisterType((*EVMContractState)(nil), "types.EVMContractState") proto.RegisterType((*EVMContractState)(nil), "types.EVMContractState")
proto.RegisterMapType((map[string][]byte)(nil), "types.EVMContractState.StorageEntry")
proto.RegisterType((*EVMContractAction)(nil), "types.EVMContractAction") proto.RegisterType((*EVMContractAction)(nil), "types.EVMContractAction")
proto.RegisterType((*ReceiptEVMContract)(nil), "types.ReceiptEVMContract") proto.RegisterType((*ReceiptEVMContract)(nil), "types.ReceiptEVMContract")
proto.RegisterType((*EVMStateChangeItem)(nil), "types.EVMStateChangeItem") proto.RegisterType((*EVMStateChangeItem)(nil), "types.EVMStateChangeItem")
proto.RegisterType((*EVMContractDataCmd)(nil), "types.EVMContractDataCmd") proto.RegisterType((*EVMContractDataCmd)(nil), "types.EVMContractDataCmd")
proto.RegisterType((*EVMContractStateCmd)(nil), "types.EVMContractStateCmd") proto.RegisterType((*EVMContractStateCmd)(nil), "types.EVMContractStateCmd")
proto.RegisterMapType((map[string]string)(nil), "types.EVMContractStateCmd.StorageEntry")
proto.RegisterType((*ReceiptEVMContractCmd)(nil), "types.ReceiptEVMContractCmd") proto.RegisterType((*ReceiptEVMContractCmd)(nil), "types.ReceiptEVMContractCmd")
proto.RegisterType((*CheckEVMAddrReq)(nil), "types.CheckEVMAddrReq") proto.RegisterType((*CheckEVMAddrReq)(nil), "types.CheckEVMAddrReq")
proto.RegisterType((*CheckEVMAddrResp)(nil), "types.CheckEVMAddrResp") proto.RegisterType((*CheckEVMAddrResp)(nil), "types.CheckEVMAddrResp")
...@@ -628,55 +1202,67 @@ func init() { ...@@ -628,55 +1202,67 @@ func init() {
proto.RegisterType((*EstimateEVMGasResp)(nil), "types.EstimateEVMGasResp") proto.RegisterType((*EstimateEVMGasResp)(nil), "types.EstimateEVMGasResp")
proto.RegisterType((*EvmDebugReq)(nil), "types.EvmDebugReq") proto.RegisterType((*EvmDebugReq)(nil), "types.EvmDebugReq")
proto.RegisterType((*EvmDebugResp)(nil), "types.EvmDebugResp") proto.RegisterType((*EvmDebugResp)(nil), "types.EvmDebugResp")
} proto.RegisterType((*EvmQueryAbiReq)(nil), "types.EvmQueryAbiReq")
proto.RegisterType((*EvmQueryAbiResp)(nil), "types.EvmQueryAbiResp")
func init() { proto.RegisterFile("evmcontract.proto", fileDescriptor0) } proto.RegisterType((*EvmQueryReq)(nil), "types.EvmQueryReq")
proto.RegisterType((*EvmQueryResp)(nil), "types.EvmQueryResp")
var fileDescriptor0 = []byte{ }
// 716 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0x41, 0x6f, 0xd3, 0x4a, func init() { proto.RegisterFile("evmcontract.proto", fileDescriptor_74353de561acd7c6) }
0x10, 0x96, 0x63, 0x27, 0x8d, 0x27, 0x79, 0xaf, 0xed, 0xbe, 0xf7, 0xfa, 0xac, 0x8a, 0x43, 0xb4,
0xa2, 0x10, 0x21, 0x11, 0xa1, 0x72, 0x41, 0x3d, 0x20, 0x55, 0xa9, 0x55, 0x90, 0x08, 0xa0, 0xad, var fileDescriptor_74353de561acd7c6 = []byte{
0x94, 0xfb, 0xd6, 0x5e, 0x52, 0xd3, 0xd8, 0x6b, 0xbc, 0xeb, 0x4a, 0xbd, 0xf2, 0x1b, 0xb8, 0x20, // 834 bytes of a gzipped FileDescriptorProto
0x71, 0x00, 0xf1, 0xcf, 0x38, 0xf1, 0x33, 0xd0, 0xee, 0x3a, 0xce, 0xda, 0x4d, 0x6f, 0x15, 0xe2, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0x4b, 0x6f, 0x2b, 0x35,
0x94, 0xf9, 0x66, 0x67, 0x3d, 0xdf, 0xcc, 0x7c, 0xb3, 0x81, 0x5d, 0x76, 0x95, 0x46, 0x3c, 0x93, 0x18, 0xd5, 0x24, 0x93, 0xc7, 0x7c, 0x09, 0xb7, 0xad, 0x81, 0x32, 0xaa, 0x58, 0x44, 0x16, 0x17,
0x05, 0x8d, 0xe4, 0x24, 0x2f, 0xb8, 0xe4, 0xa8, 0x2b, 0xaf, 0x73, 0x26, 0xf0, 0x47, 0x07, 0x76, 0xa2, 0x2b, 0x11, 0xa1, 0xcb, 0x06, 0x5d, 0x09, 0xa4, 0x28, 0x77, 0x54, 0x90, 0x08, 0x0f, 0x57,
0xc3, 0xf9, 0x6c, 0x5a, 0x1d, 0xbe, 0x39, 0x7f, 0xcf, 0x22, 0x89, 0x10, 0x78, 0x34, 0x8e, 0x8b, 0x64, 0xef, 0xcc, 0x98, 0x74, 0xda, 0xcc, 0x83, 0xb1, 0x27, 0x28, 0x5b, 0xd6, 0x2c, 0x59, 0xb2,
0xc0, 0x19, 0x39, 0x63, 0x9f, 0x68, 0x1b, 0x3d, 0x02, 0x2f, 0xa6, 0x92, 0x06, 0x9d, 0x91, 0x33, 0x63, 0xc9, 0x92, 0x1d, 0x3f, 0x87, 0x15, 0x3f, 0x03, 0x7d, 0x1e, 0xcf, 0x2b, 0x4d, 0x2a, 0x21,
0x1e, 0x1c, 0xee, 0x4d, 0xf4, 0xfd, 0x89, 0x75, 0xf7, 0x84, 0x4a, 0x4a, 0x74, 0x0c, 0x7a, 0x0c, 0x55, 0x88, 0x55, 0x7d, 0xec, 0x63, 0xfb, 0x9c, 0xf9, 0xce, 0xe7, 0x14, 0x2e, 0xc4, 0x2e, 0xf2,
0x5d, 0x21, 0xa9, 0x64, 0x81, 0xab, 0x83, 0xff, 0xbf, 0x19, 0x7c, 0xa6, 0x8e, 0x89, 0x89, 0xc2, 0x93, 0x58, 0x65, 0xdc, 0x57, 0xb3, 0x34, 0x4b, 0x54, 0x42, 0x7a, 0x6a, 0x9f, 0x0a, 0x49, 0x7f,
0x9f, 0x1d, 0xd8, 0x6e, 0x7d, 0x08, 0x05, 0xb0, 0x15, 0x15, 0x8c, 0x4a, 0xbe, 0x62, 0xb1, 0x82, 0xb2, 0xe0, 0xc2, 0x5b, 0x2d, 0x17, 0x66, 0xf1, 0xeb, 0xf5, 0x9d, 0xf0, 0x15, 0x21, 0x60, 0xf3,
0x8a, 0x5c, 0x46, 0x53, 0xa6, 0x89, 0xf8, 0x44, 0xdb, 0xe8, 0x5f, 0xe8, 0xd2, 0x65, 0x42, 0x85, 0x20, 0xc8, 0x5c, 0x6b, 0x62, 0x4d, 0x1d, 0xa6, 0xc7, 0xe4, 0x05, 0xd8, 0x01, 0x57, 0xdc, 0xed,
0x4e, 0xe8, 0x13, 0x03, 0xea, 0x32, 0x3c, 0xab, 0x0c, 0x04, 0x5e, 0xc4, 0x63, 0x16, 0x74, 0x47, 0x4c, 0xac, 0xe9, 0xe8, 0xe5, 0xe5, 0x4c, 0xef, 0x9f, 0x35, 0xf6, 0xbe, 0xe6, 0x8a, 0x33, 0xcd,
0xce, 0x78, 0x48, 0xb4, 0x8d, 0xf6, 0xa1, 0xaf, 0x7e, 0x5f, 0x50, 0x71, 0x11, 0xf4, 0xb4, 0xbf, 0x21, 0x1f, 0x42, 0x4f, 0x2a, 0xae, 0x84, 0xdb, 0xd5, 0xe4, 0x77, 0x1e, 0x92, 0x6f, 0x70, 0x99,
0xc6, 0xf8, 0x87, 0x03, 0x3b, 0x6d, 0xde, 0x2a, 0x5d, 0xc6, 0xb3, 0x88, 0x69, 0x6a, 0x1e, 0x31, 0x15, 0x2c, 0xfa, 0xbb, 0x05, 0x67, 0x07, 0x07, 0x11, 0x17, 0x06, 0x7e, 0x26, 0xb8, 0x4a, 0x4a,
0x40, 0x7d, 0x46, 0x94, 0x49, 0x94, 0xc4, 0x2c, 0xd6, 0xe4, 0xfa, 0xa4, 0xc6, 0x68, 0x04, 0x03, 0x15, 0x25, 0x44, 0x71, 0x31, 0x8f, 0x84, 0x16, 0xe2, 0x30, 0x3d, 0x26, 0x6f, 0x41, 0x8f, 0x6f,
0x21, 0x79, 0x41, 0x17, 0x26, 0x8b, 0xab, 0xb3, 0xd8, 0x2e, 0xf4, 0x1c, 0xb6, 0x2a, 0x18, 0x78, 0x43, 0x2e, 0xf5, 0x85, 0x0e, 0x2b, 0x40, 0x65, 0xc3, 0x6e, 0xd8, 0x20, 0x60, 0xfb, 0x49, 0x20,
0x23, 0x77, 0x3c, 0x38, 0xbc, 0x7f, 0x4b, 0xd7, 0x26, 0x67, 0x26, 0x2c, 0xcc, 0x64, 0x71, 0x4d, 0xdc, 0xde, 0xc4, 0x9a, 0x8e, 0x99, 0x1e, 0x93, 0x2b, 0x18, 0xe2, 0xdf, 0xcf, 0xb9, 0xbc, 0x75,
0x56, 0x97, 0xf6, 0x8f, 0x60, 0x68, 0x1f, 0xa0, 0x1d, 0x70, 0x2f, 0xd9, 0x75, 0xd5, 0x3c, 0x65, 0xfb, 0x7a, 0xbe, 0xc2, 0xe4, 0x1c, 0xba, 0x7c, 0x1d, 0xba, 0x03, 0x7d, 0x04, 0x0e, 0xe9, 0x5f,
0x2a, 0xd6, 0x57, 0x74, 0x59, 0x9a, 0xce, 0x0d, 0x89, 0x01, 0x47, 0x9d, 0x67, 0x0e, 0xfe, 0xd6, 0x16, 0x9c, 0x1f, 0x3a, 0x41, 0x01, 0x71, 0x12, 0xfb, 0x42, 0x8b, 0xb5, 0x59, 0x01, 0xf0, 0x60,
0x54, 0xc1, 0x71, 0x24, 0x13, 0x9e, 0xa1, 0x3d, 0xe8, 0xd1, 0x94, 0x97, 0x99, 0xac, 0xca, 0xac, 0x99, 0x87, 0x7e, 0x18, 0x88, 0x40, 0xcb, 0x1d, 0xb2, 0x0a, 0x93, 0x09, 0x8c, 0xa4, 0x4a, 0x32,
0x90, 0xaa, 0x73, 0x41, 0xc5, 0xab, 0x24, 0x4d, 0xa4, 0xfe, 0x94, 0x47, 0x6a, 0x5c, 0x9d, 0xbd, 0xbe, 0x29, 0xee, 0xed, 0xea, 0x7b, 0x9b, 0x53, 0xe4, 0x33, 0x18, 0x18, 0xe8, 0xda, 0x93, 0xee,
0x2d, 0x92, 0xc8, 0x0c, 0xff, 0x2f, 0x52, 0xe3, 0xba, 0xf5, 0x9e, 0xd5, 0xfa, 0x7a, 0x70, 0xdd, 0x74, 0xf4, 0xf2, 0xbd, 0x13, 0xdf, 0x71, 0x76, 0x53, 0xd0, 0xbc, 0x58, 0x65, 0x7b, 0x56, 0x6e,
0xd6, 0xe0, 0x32, 0x2e, 0x99, 0x1e, 0x86, 0x1a, 0x31, 0x97, 0x0c, 0x7f, 0x75, 0x00, 0x11, 0x16, 0xba, 0x7a, 0x05, 0xe3, 0xe6, 0x02, 0x5a, 0xb9, 0x17, 0x7b, 0xf3, 0x39, 0x71, 0x88, 0xaa, 0x77,
0xb1, 0x24, 0x97, 0x16, 0x55, 0x45, 0x32, 0xa2, 0xcb, 0x25, 0x5b, 0xc9, 0xa4, 0x42, 0x08, 0xc3, 0x7c, 0x9b, 0x17, 0xdf, 0x72, 0xcc, 0x0a, 0xf0, 0xaa, 0xf3, 0x89, 0x45, 0xff, 0x68, 0xe7, 0x62,
0x70, 0xa5, 0xf8, 0xd7, 0x6b, 0xb5, 0x34, 0x7c, 0x76, 0xcc, 0xb1, 0xd2, 0x89, 0xdb, 0x8c, 0x51, 0xee, 0xab, 0x30, 0x89, 0xc9, 0x25, 0xf4, 0x79, 0x94, 0xe4, 0xb1, 0x32, 0x36, 0x0d, 0x42, 0x9f,
0x3e, 0xa5, 0xc3, 0x52, 0xb0, 0xf8, 0x94, 0x0a, 0xcd, 0xdb, 0x23, 0x2b, 0xa8, 0x1a, 0x5c, 0x30, 0x1b, 0x2e, 0xbf, 0x0c, 0xa3, 0x50, 0xe9, 0xa3, 0x6c, 0x56, 0x61, 0xb3, 0xf6, 0x4d, 0x16, 0xfa,
0x59, 0x09, 0x49, 0x99, 0xf8, 0x1d, 0xa0, 0x70, 0x3e, 0xd3, 0x43, 0x9a, 0x5e, 0xd0, 0x6c, 0xc1, 0x45, 0x1c, 0xde, 0x60, 0x15, 0xae, 0x8a, 0x61, 0x37, 0x8a, 0x51, 0x95, 0xb2, 0x77, 0x50, 0xca,
0x5e, 0x4a, 0x96, 0x6e, 0x18, 0xc4, 0x3e, 0xf4, 0xf3, 0x82, 0xcd, 0xad, 0x59, 0xd4, 0x58, 0x73, 0x38, 0x51, 0x42, 0x97, 0x07, 0x8b, 0x9e, 0x28, 0x71, 0xa4, 0x34, 0x7f, 0x5a, 0x40, 0x98, 0xf0,
0x2a, 0x8b, 0x82, 0x65, 0xd2, 0x9c, 0x1b, 0xa5, 0x34, 0x7c, 0xf8, 0x8b, 0xa3, 0x13, 0xd9, 0xfb, 0x45, 0x98, 0xaa, 0x86, 0x78, 0x94, 0xed, 0xf3, 0xed, 0x56, 0x94, 0x51, 0x32, 0x88, 0x50, 0x18,
0x32, 0x4d, 0xe3, 0xdf, 0xb2, 0x32, 0xfe, 0x2d, 0x2b, 0xe3, 0x5b, 0x2b, 0xf3, 0xd3, 0x81, 0x7f, 0x97, 0x5d, 0xf1, 0x55, 0x9d, 0xa8, 0xd6, 0x5c, 0x93, 0x33, 0xc7, 0x2c, 0x75, 0xdb, 0x1c, 0x9c,
0xda, 0xa2, 0x55, 0xfc, 0xee, 0x64, 0x6b, 0xfc, 0xe6, 0xd6, 0x1c, 0xb7, 0xb7, 0xe6, 0xe1, 0x2d, 0xc3, 0xac, 0xe6, 0x52, 0x04, 0xd7, 0x5c, 0x6a, 0x27, 0x36, 0x2b, 0x21, 0x4a, 0xcc, 0x84, 0x32,
0x5b, 0x33, 0x4d, 0xe3, 0xbb, 0x59, 0x1c, 0xdf, 0x5e, 0x9c, 0xef, 0x0e, 0xfc, 0x77, 0x53, 0x94, 0x61, 0xc3, 0x21, 0x72, 0xef, 0x64, 0x12, 0x33, 0xa1, 0x8c, 0x97, 0x12, 0xd2, 0xef, 0x81, 0x78,
0xaa, 0xd8, 0x3f, 0x42, 0x97, 0xbe, 0xd1, 0xe5, 0x01, 0x6c, 0x4f, 0x2f, 0x58, 0x74, 0x19, 0xce, 0xab, 0xa5, 0x2e, 0xe8, 0xe2, 0x96, 0xc7, 0x1b, 0xf1, 0x85, 0x12, 0xd1, 0x91, 0xa2, 0x5d, 0xc1,
0x67, 0xea, 0x2e, 0x61, 0x1f, 0x36, 0xbd, 0xf0, 0xf8, 0x93, 0x03, 0x3b, 0xcd, 0x38, 0x91, 0x9b, 0x30, 0xcd, 0xc4, 0xaa, 0x51, 0xb7, 0x0a, 0x6b, 0xb5, 0x79, 0x96, 0x89, 0x58, 0x15, 0xeb, 0x45,
0x41, 0x9b, 0xbc, 0x3a, 0xb8, 0x4f, 0x6a, 0x7c, 0x83, 0x67, 0x67, 0x03, 0xcf, 0x76, 0xbd, 0xee, 0xaa, 0x5a, 0x73, 0xf4, 0x57, 0x4b, 0x5f, 0xd4, 0xec, 0xb6, 0x45, 0x14, 0xfc, 0x27, 0x0d, 0xe7,
0x86, 0x7a, 0xef, 0x81, 0xaf, 0xd5, 0xa7, 0x03, 0x8c, 0xf2, 0xd6, 0x0e, 0xbc, 0x80, 0xdd, 0x50, 0x9c, 0x68, 0x38, 0xa7, 0x6e, 0x38, 0xfa, 0xb7, 0x05, 0x6f, 0x1e, 0x06, 0x1c, 0xf5, 0x3d, 0x49,
0xc8, 0x24, 0xa5, 0x92, 0x85, 0xf3, 0xd9, 0x29, 0x15, 0x8a, 0xff, 0xdf, 0xd0, 0x91, 0xbc, 0x62, 0x87, 0x39, 0xed, 0x0e, 0x9b, 0x1f, 0x76, 0xd8, 0x07, 0x27, 0x3a, 0x6c, 0x11, 0x05, 0x4f, 0xd3,
0xdf, 0x91, 0xbc, 0xd6, 0x68, 0xc7, 0x7a, 0x5b, 0xd6, 0x23, 0x70, 0x1b, 0x23, 0x58, 0xbf, 0x6b, 0x64, 0x4e, 0xb3, 0xc9, 0x7e, 0xb3, 0xe0, 0xed, 0x87, 0x71, 0x45, 0xb3, 0xff, 0x8b, 0xc4, 0x3a,
0x9e, 0xfd, 0xae, 0xe1, 0x07, 0x80, 0xda, 0x89, 0x44, 0xae, 0xda, 0xb9, 0xa0, 0xa2, 0xd2, 0xac, 0x3a, 0xb1, 0xf4, 0x39, 0x9c, 0x2d, 0x6e, 0x85, 0x7f, 0xef, 0xad, 0x96, 0xb8, 0x97, 0x89, 0x1f,
0x32, 0xf1, 0x01, 0x0c, 0xc2, 0xab, 0xf4, 0x84, 0x9d, 0x97, 0x0b, 0x45, 0x65, 0x0f, 0x7a, 0x3c, 0x8e, 0xfd, 0x3e, 0xd0, 0x5f, 0x2c, 0x38, 0x6f, 0xf3, 0x64, 0x5a, 0x14, 0xba, 0xb8, 0x57, 0x93,
0x57, 0xa2, 0xd3, 0x31, 0x5d, 0x52, 0x21, 0xfc, 0x04, 0x86, 0xeb, 0x30, 0x91, 0x2b, 0x31, 0xc7, 0x87, 0xac, 0xc2, 0x0f, 0x74, 0x76, 0x8e, 0xe8, 0x3c, 0xf4, 0xdb, 0x3d, 0xe2, 0xf7, 0x5d, 0x70,
0x0a, 0x28, 0x39, 0x96, 0xa2, 0xe2, 0x6e, 0xbb, 0xce, 0x7b, 0xfa, 0xaf, 0xf9, 0xe9, 0xaf, 0x00, 0x74, 0xfa, 0x34, 0xa1, 0x48, 0x5e, 0x3d, 0x41, 0xf7, 0x70, 0xe1, 0x49, 0x15, 0x46, 0x5c, 0x09,
0x00, 0x00, 0xff, 0xff, 0xc4, 0x9f, 0x0e, 0xf7, 0xaf, 0x07, 0x00, 0x00, 0x6f, 0xb5, 0xbc, 0xe6, 0x12, 0xf5, 0x3f, 0x83, 0x8e, 0x4a, 0x8c, 0xfa, 0x8e, 0x4a, 0xaa, 0x8c,
0x76, 0x1a, 0xef, 0x50, 0x5d, 0x82, 0x6e, 0xab, 0x04, 0xf5, 0x1b, 0x68, 0xb7, 0xde, 0x40, 0xf3,
0x1a, 0xf5, 0xea, 0xd7, 0xe8, 0x7d, 0x20, 0x87, 0x57, 0xcb, 0x14, 0x79, 0x1b, 0x2e, 0x4d, 0x8a,
0x71, 0x48, 0x9f, 0xc3, 0xc8, 0xdb, 0x45, 0xaf, 0xc5, 0x3a, 0xdf, 0xa0, 0xb8, 0x4b, 0xe8, 0x27,
0x29, 0xc6, 0x50, 0x73, 0x7a, 0xcc, 0x20, 0xfa, 0x11, 0x8c, 0x6b, 0x9a, 0x4c, 0x31, 0xde, 0x01,
0x02, 0x0c, 0x68, 0x2e, 0x8d, 0x9b, 0xe6, 0x14, 0x7d, 0x01, 0xcf, 0xbc, 0x5d, 0xf4, 0x6d, 0x2e,
0xb2, 0xfd, 0x7c, 0x1d, 0xe2, 0xd9, 0x2e, 0x0c, 0xb0, 0x58, 0x42, 0x96, 0xfc, 0x12, 0xd2, 0x4f,
0xe1, 0xac, 0xc5, 0x95, 0xe9, 0x69, 0x72, 0xe9, 0xb5, 0x53, 0x7b, 0xfd, 0x4e, 0x7b, 0xd0, 0xdb,
0x1f, 0xbd, 0x07, 0xbb, 0x21, 0x8c, 0xd3, 0x5c, 0x95, 0xdd, 0xa0, 0xc1, 0xa9, 0x8f, 0x4d, 0x7f,
0xb6, 0xb4, 0x69, 0x73, 0xee, 0xa3, 0x9a, 0xfe, 0xd5, 0xc1, 0x78, 0x4e, 0xc6, 0x7f, 0xc4, 0xb7,
0xcf, 0xfc, 0xf8, 0x94, 0x10, 0x23, 0x8b, 0x2f, 0xb2, 0x5e, 0x2a, 0x8a, 0x59, 0xe1, 0x75, 0x5f,
0xff, 0xef, 0xf4, 0xf1, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x88, 0x5b, 0x84, 0x50, 0x09,
0x00, 0x00,
} }
...@@ -24,4 +24,6 @@ type CreateCallTx struct { ...@@ -24,4 +24,6 @@ type CreateCallTx struct {
Name string `json:"name"` Name string `json:"name"`
// IsCreate 是否创建合约 // IsCreate 是否创建合约
IsCreate bool `json:"isCreate"` IsCreate bool `json:"isCreate"`
// Abi 创建合约或调用合约时附带的ABI数据
Abi string `json:"abi"`
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment