// Test the given input parameter `v` and checks if it matches certain // criteria // * Big integers are checks for ptr types and if the given value is // assignable // * Integer are checked for size // * Strings, addresses and bytes are checks for type and size func (t Type) pack(v interface{}) ([]byte, error) { value := reflect.ValueOf(v) switch kind := value.Kind(); kind { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if t.Type != ubig_t { return nil, fmt.Errorf("type mismatch: %s for %T", t.Type, v) } return packNum(value, t.T), nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if t.Type != ubig_t { return nil, fmt.Errorf("type mismatch: %s for %T", t.Type, v) } return packNum(value, t.T), nil case reflect.Ptr: // If the value is a ptr do a assign check (only used by // big.Int for now) if t.Type == ubig_t && value.Type() != ubig_t { return nil, fmt.Errorf("type mismatch: %s for %T", t.Type, v) } return packNum(value, t.T), nil case reflect.String: if t.Size > -1 && value.Len() > t.Size { return nil, fmt.Errorf("%v out of bound. %d for %d", value.Kind(), value.Len(), t.Size) } return []byte(common.LeftPadString(t.String(), 32)), nil case reflect.Slice: if t.Size > -1 && value.Len() > t.Size { return nil, fmt.Errorf("%v out of bound. %d for %d", value.Kind(), value.Len(), t.Size) } // Address is a special slice. The slice acts as one rather than a list of elements. if t.T == AddressTy { return common.LeftPadBytes(v.([]byte), 32), nil } // Signed / Unsigned check if (t.T != IntTy && isSigned(value)) || (t.T == UintTy && isSigned(value)) { return nil, fmt.Errorf("slice of incompatible types.") } var packed []byte for i := 0; i < value.Len(); i++ { packed = append(packed, packNum(value.Index(i), t.T)...) } return packed, nil case reflect.Bool: if value.Bool() { return common.LeftPadBytes(common.Big1.Bytes(), 32), nil } else { return common.LeftPadBytes(common.Big0.Bytes(), 32), nil } } panic("unreached") }
func mapToTxParams(object map[string]interface{}) map[string]string { // Default values if object["from"] == nil { object["from"] = "" } if object["to"] == nil { object["to"] = "" } if object["value"] == nil { object["value"] = "" } if object["gas"] == nil { object["gas"] = "" } if object["gasPrice"] == nil { object["gasPrice"] = "" } var dataStr string var data []string if list, ok := object["data"].(*qml.List); ok { list.Convert(&data) } else if str, ok := object["data"].(string); ok { data = []string{str} } for _, str := range data { if common.IsHex(str) { str = str[2:] if len(str) != 64 { str = common.LeftPadString(str, 64) } } else { str = common.Bytes2Hex(common.LeftPadBytes(common.Big(str).Bytes(), 32)) } dataStr += str } object["data"] = dataStr conv := make(map[string]string) for key, value := range object { if v, ok := value.(string); ok { conv[key] = v } } return conv }