github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/accounts/abi/type.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2015 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package abi 26 27 import ( 28 "fmt" 29 "reflect" 30 "regexp" 31 "strconv" 32 "strings" 33 ) 34 35 //类型枚举器 36 const ( 37 IntTy byte = iota 38 UintTy 39 BoolTy 40 StringTy 41 SliceTy 42 ArrayTy 43 AddressTy 44 FixedBytesTy 45 BytesTy 46 HashTy 47 FixedPointTy 48 FunctionTy 49 ) 50 51 //类型是受支持的参数类型的反射 52 type Type struct { 53 Elem *Type 54 55 Kind reflect.Kind 56 Type reflect.Type 57 Size int 58 T byte //我们自己的类型检查 59 60 stringKind string //保留用于派生签名的未分析字符串 61 } 62 63 var ( 64 //typeregex解析ABI子类型 65 typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?") 66 ) 67 68 //new type创建在t中给定的abi类型的新反射类型。 69 func NewType(t string) (typ Type, err error) { 70 //检查数组括号是否相等(如果存在) 71 if strings.Count(t, "[") != strings.Count(t, "]") { 72 return Type{}, fmt.Errorf("invalid arg type in abi") 73 } 74 75 typ.stringKind = t 76 77 //如果有括号,准备进入切片/阵列模式 78 //递归创建类型 79 if strings.Count(t, "[") != 0 { 80 i := strings.LastIndex(t, "[") 81 //递归嵌入类型 82 embeddedType, err := NewType(t[:i]) 83 if err != nil { 84 return Type{}, err 85 } 86 //抓取最后一个单元格并从中创建类型 87 sliced := t[i:] 88 //用regexp获取切片大小 89 re := regexp.MustCompile("[0-9]+") 90 intz := re.FindAllString(sliced, -1) 91 92 if len(intz) == 0 { 93 //是一片 94 typ.T = SliceTy 95 typ.Kind = reflect.Slice 96 typ.Elem = &embeddedType 97 typ.Type = reflect.SliceOf(embeddedType.Type) 98 } else if len(intz) == 1 { 99 //是一个数组 100 typ.T = ArrayTy 101 typ.Kind = reflect.Array 102 typ.Elem = &embeddedType 103 typ.Size, err = strconv.Atoi(intz[0]) 104 if err != nil { 105 return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err) 106 } 107 typ.Type = reflect.ArrayOf(typ.Size, embeddedType.Type) 108 } else { 109 return Type{}, fmt.Errorf("invalid formatting of array type") 110 } 111 return typ, err 112 } 113 //分析ABI类型的类型和大小。 114 parsedType := typeRegex.FindAllStringSubmatch(t, -1)[0] 115 //varsize是变量的大小 116 var varSize int 117 if len(parsedType[3]) > 0 { 118 var err error 119 varSize, err = strconv.Atoi(parsedType[2]) 120 if err != nil { 121 return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err) 122 } 123 } else { 124 if parsedType[0] == "uint" || parsedType[0] == "int" { 125 //这应该失败,因为这意味着 126 //ABI类型(编译器应始终将其格式化为大小…始终) 127 return Type{}, fmt.Errorf("unsupported arg type: %s", t) 128 } 129 } 130 //vartype是解析的abi类型 131 switch varType := parsedType[1]; varType { 132 case "int": 133 typ.Kind, typ.Type = reflectIntKindAndType(false, varSize) 134 typ.Size = varSize 135 typ.T = IntTy 136 case "uint": 137 typ.Kind, typ.Type = reflectIntKindAndType(true, varSize) 138 typ.Size = varSize 139 typ.T = UintTy 140 case "bool": 141 typ.Kind = reflect.Bool 142 typ.T = BoolTy 143 typ.Type = reflect.TypeOf(bool(false)) 144 case "address": 145 typ.Kind = reflect.Array 146 typ.Type = addressT 147 typ.Size = 20 148 typ.T = AddressTy 149 case "string": 150 typ.Kind = reflect.String 151 typ.Type = reflect.TypeOf("") 152 typ.T = StringTy 153 case "bytes": 154 if varSize == 0 { 155 typ.T = BytesTy 156 typ.Kind = reflect.Slice 157 typ.Type = reflect.SliceOf(reflect.TypeOf(byte(0))) 158 } else { 159 typ.T = FixedBytesTy 160 typ.Kind = reflect.Array 161 typ.Size = varSize 162 typ.Type = reflect.ArrayOf(varSize, reflect.TypeOf(byte(0))) 163 } 164 case "function": 165 typ.Kind = reflect.Array 166 typ.T = FunctionTy 167 typ.Size = 24 168 typ.Type = reflect.ArrayOf(24, reflect.TypeOf(byte(0))) 169 default: 170 return Type{}, fmt.Errorf("unsupported arg type: %s", t) 171 } 172 173 return 174 } 175 176 //字符串实现字符串 177 func (t Type) String() (out string) { 178 return t.stringKind 179 } 180 181 func (t Type) pack(v reflect.Value) ([]byte, error) { 182 //如果指针是指针,则先取消引用指针 183 v = indirect(v) 184 185 if err := typeCheck(t, v); err != nil { 186 return nil, err 187 } 188 189 if t.T == SliceTy || t.T == ArrayTy { 190 var packed []byte 191 192 for i := 0; i < v.Len(); i++ { 193 val, err := t.Elem.pack(v.Index(i)) 194 if err != nil { 195 return nil, err 196 } 197 packed = append(packed, val...) 198 } 199 if t.T == SliceTy { 200 return packBytesSlice(packed, v.Len()), nil 201 } else if t.T == ArrayTy { 202 return packed, nil 203 } 204 } 205 return packElement(t, v), nil 206 } 207 208 //RequireLengthPrefix返回类型是否需要任何长度 209 //前缀。 210 func (t Type) requiresLengthPrefix() bool { 211 return t.T == StringTy || t.T == BytesTy || t.T == SliceTy 212 }