Solved stringified address encoding issue

This commit is contained in:
Paul Berg 2018-10-27 10:42:18 +02:00 committed by Martin Holst Swende
parent 950307bc8a
commit 9f9033710b
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
4 changed files with 59 additions and 41 deletions

View file

@ -109,7 +109,7 @@ type Wallet interface {
// a password to decrypt the account, or a PIN code to verify the transaction), // a password to decrypt the account, or a PIN code to verify the transaction),
// an AuthNeededError instance will be returned, containing infos for the user // an AuthNeededError instance will be returned, containing infos for the user
// about which fields or actions are needed. The user may retry by providing // about which fields or actions are needed. The user may retry by providing
// the needed details via SignTxWithPassphrase, or by other means (e.g. unlock // the needed details via SignHashWithPassphraseSignTxWithPassphrase, or by other means (e.g. unlock
// the account in a keystore). // the account in a keystore).
SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

View file

@ -245,3 +245,12 @@ t=2018-10-25T14:22:59+0200 lvl=info msg=SignData api=signer type=response data
t=2018-10-25T14:23:05+0200 lvl=info msg=SignData api=signer type=request metadata="{\"remote\":\"127.0.0.1:59342\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data=608af3436e40964b9f2c7214953a3f03685f62b8deadbeef content-type=text/validator t=2018-10-25T14:23:05+0200 lvl=info msg=SignData api=signer type=request metadata="{\"remote\":\"127.0.0.1:59342\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data=608af3436e40964b9f2c7214953a3f03685f62b8deadbeef content-type=text/validator
t=2018-10-25T14:23:31+0200 lvl=info msg=Configured api=signer audit log=audit.log t=2018-10-25T14:23:31+0200 lvl=info msg=Configured api=signer audit log=audit.log
t=2018-10-25T14:23:55+0200 lvl=info msg=SignData api=signer type=request metadata="{\"remote\":\"127.0.0.1:61180\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data=608af3436e40964b9f2c7214953a3f03685f62b8deadbeef content-type=text/validator t=2018-10-25T14:23:55+0200 lvl=info msg=SignData api=signer type=request metadata="{\"remote\":\"127.0.0.1:61180\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data=608af3436e40964b9f2c7214953a3f03685f62b8deadbeef content-type=text/validator
t=2018-10-25T20:12:47+0200 lvl=info msg=Configured api=signer audit log=audit.log
t=2018-10-25T20:13:00+0200 lvl=info msg=SignData api=signer type=request metadata="{\"remote\":\"127.0.0.1:59607\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data=608af3436e40964b9f2c7214953a3f03685f62b8deadbeef content-type=text/validator
t=2018-10-25T20:34:51+0200 lvl=info msg=Configured api=signer audit log=audit.log
t=2018-10-25T20:34:53+0200 lvl=info msg=SignData api=signer type=request metadata="{\"remote\":\"127.0.0.1:62187\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data=608af3436e40964b9f2c7214953a3f03685f62b8deadbeef content-type=text/validator
t=2018-10-25T20:35:38+0200 lvl=info msg=Configured api=signer audit log=audit.log
t=2018-10-25T20:35:43+0200 lvl=info msg=SignData api=signer type=request metadata="{\"remote\":\"127.0.0.1:62300\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data=608af3436e40964b9f2c7214953a3f03685f62b8deadbeef content-type=text/validator
t=2018-10-25T20:41:50+0200 lvl=info msg=Configured api=signer audit log=audit.log
t=2018-10-25T20:42:06+0200 lvl=info msg=SignData api=signer type=request metadata="{\"remote\":\"127.0.0.1:63054\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\",\"User-Agent\":\"PostmanRuntime/7.3.0\",\"Origin\":\"\"}" addr="0x66d76e6a80dc7d46d7ec1b79b15dfa34c3c6ef21 [chksum INVALID]" data=608af3436e40964b9f2c7214953a3f03685f62b8deadbeef content-type=text/validator
t=2018-10-26T10:33:40+0200 lvl=info msg=Configured api=signer audit log=audit.log

View file

@ -63,11 +63,11 @@ type EIP712TypePriority struct {
type EIP712Data = map[string]interface{} type EIP712Data = map[string]interface{}
type EIP712Domain struct { type EIP712Domain struct {
Name string `json:"name"` Name string `json:"name"`
Version string `json:"version"` Version string `json:"version"`
ChainId *big.Int `json:"chainId"` ChainId *big.Int `json:"chainId"`
VerifyingContract common.Address `json:"verifyingContract"` VerifyingContract string `json:"verifyingContract"`
Salt hexutil.Bytes `json:"salt"` Salt hexutil.Bytes `json:"salt"`
} }
const ( const (
@ -76,6 +76,7 @@ const (
TypeBytes = "bytes" TypeBytes = "bytes"
TypeInt = "int" TypeInt = "int"
TypeString = "string" TypeString = "string"
TypeUint = "uint"
) )
// Sign receives a request and produces a signature // Sign receives a request and produces a signature
@ -151,6 +152,7 @@ func (api *SignerAPI) determineSignatureFormat(contentType string, addr common.M
return nil, errors.New("no data to sign") return nil, errors.New("no data to sign")
} }
sighash, msg := SignTextValidator(data) sighash, msg := SignTextValidator(data)
fmt.Printf("%s", sighash)
req = &SignDataRequest{Rawdata: data, Message: msg, Hash: sighash, ContentType: mediaType} req = &SignDataRequest{Rawdata: data, Message: msg, Hash: sighash, ContentType: mediaType}
break break
case TextPlain.Mime: case TextPlain.Mime:
@ -185,8 +187,8 @@ func (api *SignerAPI) determineSignatureFormat(contentType string, addr common.M
// hash = keccak256("\x19\x00"${address}${data}). // hash = keccak256("\x19\x00"${address}${data}).
func SignTextValidator(data hexutil.Bytes) (hexutil.Bytes, string) { func SignTextValidator(data hexutil.Bytes) (hexutil.Bytes, string) {
address := common.BytesToAddress(data[:common.AddressLength]) address := common.BytesToAddress(data[:common.AddressLength])
message := data[common.AddressLength:len(data)-1] message := data[common.AddressLength:]
hash := fmt.Sprintf("\x19\x00:%x%s", address, string(message)) hash := fmt.Sprintf("\x19\x00%s%s", address, string(message))
return crypto.Keccak256(hexutil.Bytes(hash)), hash return crypto.Keccak256(hexutil.Bytes(hash)), hash
} }
@ -335,20 +337,23 @@ func (typedData *TypedData) TypeHash(primaryType string) hexutil.Bytes {
} }
func bytesValueOf(_interface interface{}) hexutil.Bytes { func bytesValueOf(_interface interface{}) hexutil.Bytes {
bytesVal, ok := _interface.(hexutil.Bytes) bytesValue, ok := _interface.(hexutil.Bytes)
if ok { if ok {
return bytesVal return bytesValue
} }
switch reflect.TypeOf(_interface) { switch reflect.TypeOf(_interface) {
case reflect.TypeOf(hexutil.Bytes{}):
return _interface.(hexutil.Bytes)
case reflect.TypeOf([]uint8{}):
return _interface.([]uint8)
case reflect.TypeOf(string("")): case reflect.TypeOf(string("")):
return hexutil.Bytes(_interface.(string)) return hexutil.Bytes(_interface.(string))
break
default: default:
break break
} }
panic(fmt.Errorf("unrecognized interface %v", _interface)) panic(fmt.Errorf("unrecognized interface type %T", _interface))
return hexutil.Bytes{} return hexutil.Bytes{}
} }
@ -376,7 +381,7 @@ func (typedData *TypedData) EncodeData(primaryType string, data map[string]inter
for i := 0; i < 12; i++ { for i := 0; i < 12; i++ {
bytesValue = append(bytesValue, 0) bytesValue = append(bytesValue, 0)
} }
for _, _byte := range encValue.(common.Address) { for _, _byte := range common.HexToAddress(encValue.(string)) {
bytesValue = append(bytesValue, _byte) bytesValue = append(bytesValue, _byte)
} }
primitiveEncValue = bytesValue primitiveEncValue = bytesValue
@ -575,19 +580,35 @@ func (types *EIP712Types) IsValid() error {
} }
// isStandardType checks if the given type is a EIP712 conformant type // isStandardType checks if the given type is a EIP712 conformant type
func isStandardTypeStr(typeStr string) bool { func isStandardTypeStr(encType string) bool {
standardTypes := []string{ // Atomic types
for _, standardType := range []string{
TypeAddress, TypeAddress,
TypeBool, TypeBool,
TypeBytes, TypeBytes,
TypeInt,
TypeString, TypeString,
} } {
for _, val := range standardTypes { if standardType == encType {
if strings.HasPrefix(typeStr, val) || strings.Contains(typeStr, val) {
return true return true
} }
} }
// Dynamic types
for _, standardType := range []string {
TypeBytes,
TypeInt,
TypeUint,
} {
if strings.HasPrefix(encType, standardType) {
return true
}
}
// Reference types
if encType[len(encType)-1] == ']' {
return true
}
return false return false
} }
@ -628,14 +649,3 @@ func (domain *EIP712Domain) Map() map[string]interface{} {
} }
return dataMap return dataMap
} }
// PrintJson will be removed
func printJson(label string, output map[string]interface{}) {
jsonVal, err := json.MarshalIndent(output, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s:", label)
fmt.Print(string(jsonVal))
fmt.Print("\n\n")
}

View file

@ -76,18 +76,18 @@ var domainStandard = EIP712Domain{
"Ether Mail", "Ether Mail",
"1", "1",
big.NewInt(1), big.NewInt(1),
common.HexToAddress("0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"), "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
nil, nil,
} }
var dataStandard = map[string]interface{}{ var dataStandard = map[string]interface{}{
"from": map[string]interface{}{ "from": map[string]interface{}{
"name": "Cow", "name": "Cow",
"wallet": common.HexToAddress("0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"), "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
}, },
"to": map[string]interface{}{ "to": map[string]interface{}{
"name": "Bob", "name": "Bob",
"wallet": common.HexToAddress("0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"), "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
}, },
"contents": "Hello, Bob!", "contents": "Hello, Bob!",
} }
@ -148,37 +148,36 @@ func TestSignData(t *testing.T) {
if signature == nil || len(signature) != 65 { if signature == nil || len(signature) != 65 {
t.Errorf("Expected 65 byte signature (got %d bytes)", len(signature)) t.Errorf("Expected 65 byte signature (got %d bytes)", len(signature))
} }
// TODO: test signature r,s,v values
} }
func TestHashStruct(t *testing.T) { func TestHashStruct(t *testing.T) {
mainHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.HashStruct(typedData.PrimaryType, typedData.Message))) mainHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.HashStruct(typedData.PrimaryType, typedData.Message)))
if mainHash != "0xc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e" { if mainHash != "0xc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e" {
t.Fatal(fmt.Errorf("hashStruct result %s is incorrect", mainHash)) t.Errorf("Expected different hashStruct result (got %s)", mainHash)
} }
domainHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.HashStruct("EIP712Domain", typedData.Domain.Map()))) domainHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.HashStruct("EIP712Domain", typedData.Domain.Map())))
if domainHash != "0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f" { if domainHash != "0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f" {
t.Fatal(fmt.Errorf("hashStruct result %s is incorrect", domainHash)) t.Errorf("Expected different hashStruct result (got %s)", domainHash)
} }
} }
func TestEncodeType(t *testing.T) { func TestEncodeType(t *testing.T) {
domainTypeEncoding := string(typedData.EncodeType("EIP712Domain")) domainTypeEncoding := string(typedData.EncodeType("EIP712Domain"))
if domainTypeEncoding != "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" { if domainTypeEncoding != "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" {
t.Fatal(fmt.Errorf("encodeType result %s is incorrect", domainTypeEncoding)) t.Errorf("Expected different encodeType result (got %s)", domainTypeEncoding)
} }
mailTypeEncoding := string(typedData.EncodeType(typedData.PrimaryType)) mailTypeEncoding := string(typedData.EncodeType(typedData.PrimaryType))
if mailTypeEncoding != "Mail(Person from,Person to,string contents)Person(string name,address wallet)" { if mailTypeEncoding != "Mail(Person from,Person to,string contents)Person(string name,address wallet)" {
t.Fatal(fmt.Errorf("encodeType result %s is incorrect", mailTypeEncoding)) t.Errorf("Expected different encodeType result (got %s)", mailTypeEncoding)
} }
} }
func TestTypeHash(t *testing.T) { func TestTypeHash(t *testing.T) {
mailTypeHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.TypeHash(typedData.PrimaryType))) mailTypeHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.TypeHash(typedData.PrimaryType)))
if mailTypeHash != "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2" { if mailTypeHash != "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2" {
t.Fatal(fmt.Errorf("typeHash result %s is incorrect", mailTypeHash)) t.Errorf("Expected different typeHash result (got %s)", mailTypeHash)
} }
} }
@ -186,6 +185,6 @@ func TestEncodeData(t *testing.T) {
dataEncoding := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.EncodeData(typedData.PrimaryType, typedData.Message))) dataEncoding := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.EncodeData(typedData.PrimaryType, typedData.Message)))
if dataEncoding != "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8" { if dataEncoding != "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8" {
t.Fatal(fmt.Errorf("encodeData result %s is incorrect", dataEncoding)) t.Errorf("Expected different encodeData result (got %s)", dataEncoding)
} }
} }