github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/accounts/abi/reflect.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:26</date> 10 //</624342583904047104> 11 12 13 package abi 14 15 import ( 16 "fmt" 17 "reflect" 18 "strings" 19 ) 20 21 //间接递归地取消对值的引用,直到它得到值为止 22 //或者找到一个大的.int 23 func indirect(v reflect.Value) reflect.Value { 24 if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT { 25 return indirect(v.Elem()) 26 } 27 return v 28 } 29 30 //ReflectIntKind返回使用给定大小和 31 //不拘一格 32 func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) { 33 switch size { 34 case 8: 35 if unsigned { 36 return reflect.Uint8, uint8T 37 } 38 return reflect.Int8, int8T 39 case 16: 40 if unsigned { 41 return reflect.Uint16, uint16T 42 } 43 return reflect.Int16, int16T 44 case 32: 45 if unsigned { 46 return reflect.Uint32, uint32T 47 } 48 return reflect.Int32, int32T 49 case 64: 50 if unsigned { 51 return reflect.Uint64, uint64T 52 } 53 return reflect.Int64, int64T 54 } 55 return reflect.Ptr, bigT 56 } 57 58 //mustArrayToBytesSlice创建与值大小完全相同的新字节片 59 //并将值中的字节复制到新切片。 60 func mustArrayToByteSlice(value reflect.Value) reflect.Value { 61 slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len()) 62 reflect.Copy(slice, value) 63 return slice 64 } 65 66 //设置尝试通过设置、复制或其他方式将SRC分配给DST。 67 // 68 //当涉及到任务时,set要宽松一点,而不是强制 69 //严格的规则集为bare`reflect`的规则集。 70 func set(dst, src reflect.Value, output Argument) error { 71 dstType := dst.Type() 72 srcType := src.Type() 73 switch { 74 case dstType.AssignableTo(srcType): 75 dst.Set(src) 76 case dstType.Kind() == reflect.Interface: 77 dst.Set(src) 78 case dstType.Kind() == reflect.Ptr: 79 return set(dst.Elem(), src, output) 80 default: 81 return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type()) 82 } 83 return nil 84 } 85 86 //RequiresSignable确保“dest”是指针,而不是接口。 87 func requireAssignable(dst, src reflect.Value) error { 88 if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface { 89 return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type()) 90 } 91 return nil 92 } 93 94 //RequireUnpackKind验证将“args”解包为“kind”的前提条件 95 func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, 96 args Arguments) error { 97 98 switch k { 99 case reflect.Struct: 100 case reflect.Slice, reflect.Array: 101 if minLen := args.LengthNonIndexed(); v.Len() < minLen { 102 return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d", 103 minLen, v.Len()) 104 } 105 default: 106 return fmt.Errorf("abi: cannot unmarshal tuple into %v", t) 107 } 108 return nil 109 } 110 111 //mapabitoStringField将abi映射到结构字段。 112 //第一轮:对于每个包含“abi:”标记的可导出字段 113 //这个字段名存在于参数中,将它们配对在一起。 114 //第二轮:对于每个尚未链接的参数字段, 115 //如果变量存在且尚未映射,则查找该变量应映射到的对象。 116 //用过,配对。 117 func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]string, error) { 118 119 typ := value.Type() 120 121 abi2struct := make(map[string]string) 122 struct2abi := make(map[string]string) 123 124 //第一轮~~~ 125 for i := 0; i < typ.NumField(); i++ { 126 structFieldName := typ.Field(i).Name 127 128 //跳过私有结构字段。 129 if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) { 130 continue 131 } 132 133 //跳过没有abi:“”标记的字段。 134 var ok bool 135 var tagName string 136 if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok { 137 continue 138 } 139 140 //检查标签是否为空。 141 if tagName == "" { 142 return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName) 143 } 144 145 //检查哪个参数字段与ABI标记匹配。 146 found := false 147 for _, abiField := range args.NonIndexed() { 148 if abiField.Name == tagName { 149 if abi2struct[abiField.Name] != "" { 150 return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName) 151 } 152 //配对他们 153 abi2struct[abiField.Name] = structFieldName 154 struct2abi[structFieldName] = abiField.Name 155 found = true 156 } 157 } 158 159 //检查此标记是否已映射。 160 if !found { 161 return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName) 162 } 163 164 } 165 166 //第二轮~~~ 167 for _, arg := range args { 168 169 abiFieldName := arg.Name 170 structFieldName := capitalise(abiFieldName) 171 172 if structFieldName == "" { 173 return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct") 174 } 175 176 //这个ABI已经配对了,跳过它…除非存在另一个尚未分配的 177 //具有相同字段名的结构字段。如果是,则引发错误: 178 //ABI:[“name”:“value”] 179 //结构value*big.int,value1*big.int`abi:“value”` 180 if abi2struct[abiFieldName] != "" { 181 if abi2struct[abiFieldName] != structFieldName && 182 struct2abi[structFieldName] == "" && 183 value.FieldByName(structFieldName).IsValid() { 184 return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", abiFieldName) 185 } 186 continue 187 } 188 189 //如果此结构字段已配对,则返回错误。 190 if struct2abi[structFieldName] != "" { 191 return nil, fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", structFieldName) 192 } 193 194 if value.FieldByName(structFieldName).IsValid() { 195 //配对他们 196 abi2struct[abiFieldName] = structFieldName 197 struct2abi[structFieldName] = abiFieldName 198 } else { 199 //不是成对的,而是按使用进行注释,以检测 200 //ABI:[“name”:“value”,“name”:“value”] 201 //结构值*big.int 202 struct2abi[structFieldName] = abiFieldName 203 } 204 205 } 206 207 return abi2struct, nil 208 } 209