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