github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/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 19:16:31</date> 10 //</624450062663028736> 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) error { 71 dstType, srcType := dst.Type(), src.Type() 72 switch { 73 case dstType.Kind() == reflect.Interface: 74 return set(dst.Elem(), src) 75 case dstType.Kind() == reflect.Ptr && dstType.Elem() != derefbigT: 76 return set(dst.Elem(), src) 77 case srcType.AssignableTo(dstType) && dst.CanSet(): 78 dst.Set(src) 79 case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice: 80 return setSlice(dst, src) 81 default: 82 return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type()) 83 } 84 return nil 85 } 86 87 //当切片在默认情况下不可分配时,setslice尝试将src分配给dst 88 //例如,SRC:[]字节->DST:[[15]字节 89 func setSlice(dst, src reflect.Value) error { 90 slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len()) 91 for i := 0; i < src.Len(); i++ { 92 v := src.Index(i) 93 reflect.Copy(slice.Index(i), v) 94 } 95 96 dst.Set(slice) 97 return nil 98 } 99 100 //RequiresSignable确保“dest”是指针,而不是接口。 101 func requireAssignable(dst, src reflect.Value) error { 102 if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface { 103 return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type()) 104 } 105 return nil 106 } 107 108 //RequireUnpackKind验证将“args”解包为“kind”的前提条件 109 func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, 110 args Arguments) error { 111 112 switch k { 113 case reflect.Struct: 114 case reflect.Slice, reflect.Array: 115 if minLen := args.LengthNonIndexed(); v.Len() < minLen { 116 return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d", 117 minLen, v.Len()) 118 } 119 default: 120 return fmt.Errorf("abi: cannot unmarshal tuple into %v", t) 121 } 122 return nil 123 } 124 125 //mapargnamestostructfields将参数名的一部分映射到结构字段。 126 //第一轮:对于每个包含“abi:”标记的可导出字段 127 //这个字段名存在于给定的参数名列表中,将它们配对在一起。 128 //第二轮:对于每个尚未链接的参数名, 129 //如果变量存在且尚未映射,则查找该变量应映射到的对象。 130 //用过,配对。 131 //注意:此函数假定给定值是结构值。 132 func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[string]string, error) { 133 typ := value.Type() 134 135 abi2struct := make(map[string]string) 136 struct2abi := make(map[string]string) 137 138 //第一轮~~~ 139 for i := 0; i < typ.NumField(); i++ { 140 structFieldName := typ.Field(i).Name 141 142 //跳过私有结构字段。 143 if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) { 144 continue 145 } 146 //跳过没有abi:“”标记的字段。 147 var ok bool 148 var tagName string 149 if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok { 150 continue 151 } 152 //检查标签是否为空。 153 if tagName == "" { 154 return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName) 155 } 156 //检查哪个参数字段与ABI标记匹配。 157 found := false 158 for _, arg := range argNames { 159 if arg == tagName { 160 if abi2struct[arg] != "" { 161 return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName) 162 } 163 //配对他们 164 abi2struct[arg] = structFieldName 165 struct2abi[structFieldName] = arg 166 found = true 167 } 168 } 169 //检查此标记是否已映射。 170 if !found { 171 return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName) 172 } 173 } 174 175 //第二轮~~~ 176 for _, argName := range argNames { 177 178 structFieldName := ToCamelCase(argName) 179 180 if structFieldName == "" { 181 return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct") 182 } 183 184 //这个ABI已经配对了,跳过它…除非存在另一个尚未分配的 185 //具有相同字段名的结构字段。如果是,则引发错误: 186 //ABI:[“name”:“value”] 187 //结构value*big.int,value1*big.int`abi:“value”` 188 if abi2struct[argName] != "" { 189 if abi2struct[argName] != structFieldName && 190 struct2abi[structFieldName] == "" && 191 value.FieldByName(structFieldName).IsValid() { 192 return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", argName) 193 } 194 continue 195 } 196 197 //如果此结构字段已配对,则返回错误。 198 if struct2abi[structFieldName] != "" { 199 return nil, fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", structFieldName) 200 } 201 202 if value.FieldByName(structFieldName).IsValid() { 203 //配对他们 204 abi2struct[argName] = structFieldName 205 struct2abi[structFieldName] = argName 206 } else { 207 //不是成对的,而是按使用进行注释,以检测 208 //ABI:[“name”:“value”,“name”:“value”] 209 //结构值*big.int 210 struct2abi[structFieldName] = argName 211 } 212 } 213 return abi2struct, nil 214 } 215