Commit 9cc23096 authored by Litian's avatar Litian

temp

parent 066afd76
package abi package abi
import (
"fmt"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/golang-collections/collections/stack"
"reflect"
"strconv"
)
// Pack 使用ABI方式调用时,将调用方式转换为EVM底层处理的十六进制编码 // Pack 使用ABI方式调用时,将调用方式转换为EVM底层处理的十六进制编码
// abiData 完整的ABI定义 // abiData 完整的ABI定义
// param 调用方法及参数 // param 调用方法及参数
...@@ -13,3 +21,170 @@ func Pack(param, abiData string) ([]byte, error) { ...@@ -13,3 +21,170 @@ func Pack(param, abiData string) ([]byte, error) {
func Unpack(data []byte, abiData string) (string, error) { func Unpack(data []byte, abiData string) (string, error) {
return "", nil return "", nil
} }
// 从字符串格式的输入参数取值(单个),获取Go类型的
func goValue(typ Type, val string) (res interface{}, err error) {
switch typ.T {
case IntTy:
bitSize := 0
pos := uint(typ.Kind - reflect.Int)
if pos > 0 {
bitSize = (2 << pos) * 2
}
x, err := strconv.ParseInt(val, 10, bitSize)
if err != nil {
return res, err
}
return x, nil
case UintTy:
bitSize := 0
pos := uint(typ.Kind - reflect.Uint)
if pos > 0 {
bitSize = (2 << pos) * 2
}
x, err := strconv.ParseUint(val, 10, bitSize)
if err != nil {
return res, err
}
return x, nil
case BoolTy:
x, err := strconv.ParseBool(val)
if err != nil {
return res, err
}
return x, nil
case StringTy:
return val, nil
//case SliceTy:
// var data []interface{}
// subs, err := getSubArrayStr(val)
// if err != nil {
// return res, err
// }
// for idx, sub := range subs {
// subVal, er := goValue(*typ.Elem, sub)
// if er != nil {
// return res, er
// }
// data[idx] = subVal
// }
// return data, nil
//case ArrayTy:
// var data [typ.Size]interface{}
// subs, err := getSubArrayStr(val)
// if err != nil {
// return res, err
// }
// for idx, sub := range subs {
// subVal, er := goValue(*typ.Elem, sub)
// if er != nil {
// return res, er
// }
// data[idx] = subVal
// }
// return data, nil
case AddressTy:
addr := common.StringToAddress(val)
if addr == nil {
return res, fmt.Errorf("invalid address: %v", val)
}
return addr.ToHash160(), nil
case FixedBytesTy:
//rtype := reflect.ArrayOf(typ.Size, reflect.TypeOf(byte(0)))
//value := reflect.New(rtype).Elem()
//value.SetBytes(x)
// 固定长度多字节,输入时以十六进制方式表示,如 0xabcd00ff
//x, err := common.HexToBytes(val)
//if err != nil {
// return res, err
//}
//var data [typ.Size]byte
//copy(data[:], x)
//return data, nil
case BytesTy:
// 单个字节,输入时以十六进制方式表示,如 0xab
x, err := common.HexToBytes(val)
if err != nil {
return res, err
}
return x[0], nil
case HashTy:
// 哈希类型,也是以十六进制为输入,如:0xabcdef
x, err := common.HexToBytes(val)
if err != nil {
return res, err
}
return common.BytesToHash(x), nil
default:
return res, fmt.Errorf("not support type: %v", typ.stringKind)
}
return res, nil
}
// 本方法可以将一个表示数组的字符串,经过处理后,返回数组内的字面元素;
// 如果数组为多层,则只返回第一级
// 例如:"[a,b,c]" -> "a","b","c"
// 例如:"[[a,b],[c,d]]" -> "[a,b]", "[c,d]"
// 因为格式比较复杂,正则表达式不适合处理,所以使用栈的方式来处理
func procArrayItem(val string) (res []string, err error) {
ss := stack.New()
data := []rune{}
for _, b := range val {
switch b {
case ' ':
// 只有字符串元素中间的空格才是有效的
if ss.Len() > 0 && stackPeek(ss) == '"' {
data = append(data, b)
}
case ',':
// 逗号有可能是多级数组里面的分隔符,我们只处理最外层数组的分隔,
// 因此,需要判断当前栈中是否只有一个'[',否则就当做普通内容对待
if ss.Len() == 1 && stackPeek(ss) == '[' {
// 当前元素结束
res = append(res, string(data))
data = []rune{}
} else {
data = append(data, b)
}
case '"':
// 双引号首次出现时需要入栈,下次出现时需要将两者之间的内容进行拼接
if ss.Peek() == b {
ss.Pop()
} else {
ss.Push(b)
}
//data = append(data, b)
case '[':
// 只有当栈为空时,'['才会当做数组的开始,否则全部视作普通内容
if ss.Len() == 0 {
data = []rune{}
} else {
data = append(data, b)
}
ss.Push(b)
case ']':
// 只有当栈中只有一个']'时,才会被当做数组结束,否则就当做普通内容对待
if ss.Len() == 1 && stackPeek(ss) == '[' {
// 整个数组结束
res = append(res, string(data))
} else {
data = append(data, b)
}
ss.Pop()
default:
// 其它情况全部视作普通内容
data = append(data, b)
}
}
if ss.Len() != 0 {
return nil, fmt.Errorf("invalid array format:%v", val)
}
return res, err
}
func stackPeek(ss *stack.Stack) rune {
return ss.Peek().(rune)
}
\ No newline at end of file
package abi
import (
"bytes"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/stretchr/testify/assert"
"math/big"
"reflect"
"testing"
"fmt"
)
func TestABI_Pack(t *testing.T) {
rtype := reflect.ArrayOf(4, reflect.TypeOf(byte(0)))
value := reflect.New(rtype).Elem()
value.Index(0).Set(reflect.ValueOf(byte(1)))
fmt.Println(value.Type())
fmt.Println(reflect.TypeOf([4]byte{1,0,0,0}))
//value.SetBytes([]byte("hell"))
//value.SetString("hell")
//value.Index(0).SetBytes([]byte("hell"))
}
func setArray(size int, ty reflect.Type, vals []interface{}) reflect.Value {
rtype := reflect.ArrayOf(4, reflect.TypeOf(byte(0)))
value := reflect.New(rtype).Elem()
value.Index(0).Set(reflect.ValueOf(byte(1)))
}
func TestABI_Unpack(t *testing.T) {
}
func TestProcArray(t *testing.T) {
for _, test := range []struct {
input string
output []string
}{
{
"[1,2,3]",
[]string{"1", "2", "3"},
},
{
"[[1,2,3],[4,5]]",
[]string{"[1,2,3]", "[4,5]"},
},
{
`["abc","def", "x,y, z"]`,
[]string{"abc", "def", "x,y, z"},
},
{
`["[1,2,3]"]`,
[]string{"[1,2,3]"},
},
} {
res, err := procArrayItem(test.input)
assert.NoError(t, err, "process array string error")
assert.EqualValues(t, test.output, res, "parse array string error")
}
}
func TestArgument_Pack(t *testing.T) {
for i, test := range []struct {
typ string
input interface{}
output []byte
}{
{
"uint8",
"2",
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint8[]",
[]uint8{1, 2},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint16",
uint16(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint16[]",
[]uint16{1, 2},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint32",
uint32(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint32[]",
[]uint32{1, 2},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint64",
uint64(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint64[]",
[]uint64{1, 2},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint256",
big.NewInt(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint256[]",
[]*big.Int{big.NewInt(1), big.NewInt(2)},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int8",
int8(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int8[]",
[]int8{1, 2},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int16",
int16(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int16[]",
[]int16{1, 2},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int32",
int32(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int32[]",
[]int32{1, 2},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int64",
int64(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int64[]",
[]int64{1, 2},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int256",
big.NewInt(2),
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int256[]",
[]*big.Int{big.NewInt(1), big.NewInt(2)},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"bytes1",
[1]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes2",
[2]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes3",
[3]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes4",
[4]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes5",
[5]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes6",
[6]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes7",
[7]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes8",
[8]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes9",
[9]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes10",
[10]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes11",
[11]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes12",
[12]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes13",
[13]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes14",
[14]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes15",
[15]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes16",
[16]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes17",
[17]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes18",
[18]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes19",
[19]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes20",
[20]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes21",
[21]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes22",
[22]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes23",
[23]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes24",
[24]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes24",
[24]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes25",
[25]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes26",
[26]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes27",
[27]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes28",
[28]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes29",
[29]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes30",
[30]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes31",
[31]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"bytes32",
[32]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"uint32[2][3][4]",
[4][3][2]uint32{{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000018"),
},
{
"address[]",
[]common.Hash160Address{{1}, {2}},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000"),
},
{
"bytes32[]",
[]common.Hash{{1}, {2}},
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000201000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000"),
},
{
"function",
[24]byte{1},
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
"string",
"foobar",
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000006666f6f6261720000000000000000000000000000000000000000000000000000"),
},
} {
typ, err := NewType(test.typ)
if err != nil {
t.Fatalf("%v failed. Unexpected parse error: %v", i, err)
}
output, err := typ.pack(reflect.ValueOf(test.input))
if err != nil {
t.Fatalf("%v failed. Unexpected pack error: %v", i, err)
}
if !bytes.Equal(output, test.output) {
t.Errorf("%d failed. Expected bytes: '%x' Got: '%x'", i, test.output, output)
}
}
}
...@@ -6,8 +6,9 @@ package common ...@@ -6,8 +6,9 @@ package common
import ( import (
"encoding/hex" "encoding/hex"
"sort"
"math/big" "math/big"
"sort"
"strings"
) )
// RightPadBytes 右填充字节数组 // RightPadBytes 右填充字节数组
...@@ -64,6 +65,14 @@ func Hex2Bytes(str string) []byte { ...@@ -64,6 +65,14 @@ func Hex2Bytes(str string) []byte {
return h return h
} }
// HexToBytes 十六进制字符串转换为字节数组
func HexToBytes(str string) ([]byte, error) {
if len(str) > 1 && (strings.HasPrefix(str, "0x") || strings.HasPrefix(str, "0X")) {
str = str[2:]
}
return hex.DecodeString(str)
}
// Bytes2Hex 将字节数组转换为16进制的字符串表示 // Bytes2Hex 将字节数组转换为16进制的字符串表示
func Bytes2Hex(b []byte) string { func Bytes2Hex(b []byte) string {
enc := make([]byte, len(b)*2+2) enc := make([]byte, len(b)*2+2)
......
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