mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
cmd/signer: work on abi parser
This commit is contained in:
parent
08301bbcc0
commit
37552ecc22
5 changed files with 64 additions and 8 deletions
|
|
@ -102,6 +102,12 @@ func parseCallData(calldata []byte, abidata string) (*decodedCallData, error) {
|
|||
was := common.Bytes2Hex(calldata)
|
||||
return nil, fmt.Errorf("WARNING: Supplied data is stuffed with extra data. %v \nWant %s\nHave %s", decoded,was, exp)
|
||||
}
|
||||
|
||||
return &decoded, nil
|
||||
}
|
||||
|
||||
func lookupABI(id []byte) (string, error){
|
||||
if len(id) != 4{
|
||||
return "", fmt.Errorf("Expected 4-byte id, got %d", len(id))
|
||||
}
|
||||
return `[{"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]}]`, nil
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func TestMartin(t *testing.T) {
|
||||
func TestCalldataDecoding(t *testing.T) {
|
||||
|
||||
// send(uint256) : a52c101e
|
||||
// compareAndApprove(address,uint256,uint256) : 751e1079
|
||||
|
|
@ -41,11 +41,19 @@ func TestMartin(t *testing.T) {
|
|||
"a52c101e",
|
||||
"a52c10",
|
||||
"",
|
||||
// Too short
|
||||
"751e10790000000000000000000000000000000000000000000000000000000000000012",
|
||||
"751e1079FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
//Not valid multiple of 32
|
||||
"deadbeef00000000000000000000000000000000000000000000000000000000000000",
|
||||
//Too short 'issue'
|
||||
"42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
|
||||
// Too short compareAndApprove
|
||||
"a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
|
||||
// From https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
|
||||
// contains a bool with illegal values
|
||||
"a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
|
||||
|
||||
} {
|
||||
_, err := parseCallData(common.Hex2Bytes(hexdata), jsondata)
|
||||
if err == nil {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ import (
|
|||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
//type Stringer interface {String()}
|
||||
|
||||
|
||||
type SignerAPI struct {
|
||||
chainID *big.Int
|
||||
am *accounts.Manager
|
||||
|
|
@ -64,6 +67,7 @@ type Credentials struct {
|
|||
type SignTxRequest struct {
|
||||
transaction *types.Transaction
|
||||
from accounts.Account
|
||||
callinfo fmt.Stringer
|
||||
}
|
||||
type SignTxResponse struct {
|
||||
hash common.Hash
|
||||
|
|
@ -112,6 +116,13 @@ type ListRequest struct {
|
|||
type ListResponse struct {
|
||||
accounts []Account
|
||||
}
|
||||
type errorWrapper struct{
|
||||
msg string
|
||||
err error
|
||||
}
|
||||
func (ew errorWrapper) String() string{
|
||||
return fmt.Sprintf("%s\n%s", ew.msg, ew.err)
|
||||
}
|
||||
|
||||
// SignerUI specifies what method a UI needs to implement to be able to be used as a UI
|
||||
// for the signer
|
||||
|
|
@ -269,8 +280,24 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, from common.Address,
|
|||
tx = types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), (*big.Int)(args.Gas), (*big.Int)(args.GasPrice), args.Data)
|
||||
}
|
||||
|
||||
req := SignTxRequest{transaction: tx, from: acc}
|
||||
if len(tx.Data()) > 3{
|
||||
var abidef string
|
||||
|
||||
// Try to make sense of the data
|
||||
abidef, err = lookupABI(tx.Data()[:4])
|
||||
if err != nil{
|
||||
req.callinfo = errorWrapper{"Warning! Could not locate ABI", err}
|
||||
}else{
|
||||
req.callinfo, err = parseCallData(tx.Data(),abidef)
|
||||
if err != nil{
|
||||
req.callinfo = errorWrapper{"Warning! Could not validate ABI-data against calldata", err}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ch := make(chan SignTxResponse, 1)
|
||||
api.ui.ApproveTx(&SignTxRequest{transaction: tx, from: acc}, metaData(ctx), ch)
|
||||
api.ui.ApproveTx(&req, metaData(ctx), ch)
|
||||
|
||||
if result := <-ch; result.approved {
|
||||
//Sanity check
|
||||
|
|
|
|||
|
|
@ -71,19 +71,28 @@ func (ui *CommandlineUI) confirm() bool {
|
|||
}
|
||||
|
||||
func showMetadata(metadata Metadata) {
|
||||
fmt.Printf("Request info: %v -> %v -> %v\n", metadata.remote, metadata.scheme, metadata.local)
|
||||
fmt.Printf("Request info:\n\t%v -> %v -> %v\n", metadata.remote, metadata.scheme, metadata.local)
|
||||
}
|
||||
|
||||
// ApproveTx prompt the user for confirmation to request to sign transaction
|
||||
func (ui *CommandlineUI) ApproveTx(request *SignTxRequest, metadata Metadata, ch chan SignTxResponse) {
|
||||
|
||||
weival := request.transaction.Value()
|
||||
|
||||
fmt.Printf("--------- Transaction request-------------\n")
|
||||
fmt.Printf("to: %v\n", request.transaction.To())
|
||||
fmt.Printf("from: %v\n", request.from)
|
||||
fmt.Printf("value: %v\n", request.transaction.Value())
|
||||
fmt.Printf("to: %v\n", request.transaction.To().Hex())
|
||||
fmt.Printf("from: %v\n", request.from.Address.Hex())
|
||||
fmt.Printf("value: %v wei\n", weival)
|
||||
fmt.Printf("data: %v\n", common.Bytes2Hex(request.transaction.Data()))
|
||||
fmt.Printf("-------------------------------------------\n")
|
||||
if request.callinfo != nil{
|
||||
fmt.Printf("\nNote: This transaction contains data. Review abi-decoding info below:")
|
||||
fmt.Printf("\nCall info:\n\t%v\n", request.callinfo.String())
|
||||
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
showMetadata(metadata)
|
||||
fmt.Printf("-------------------------------------------\n")
|
||||
|
||||
ch <- SignTxResponse{request.transaction.Hash(), ui.confirm(), ""}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,12 @@ func main() {
|
|||
|
||||
// List accounts
|
||||
// curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_list","params":[""],"id":67}' http://localhost:8550/
|
||||
|
||||
// Make transaction
|
||||
// send(0x12)
|
||||
// a52c101e0000000000000000000000000000000000000000000000000000000000000012
|
||||
// curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":["0x82A2A876D39022B3019932D30Cd9c97ad5616813","pw",{"gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "input":"0xa52c101e0000000000000000000000000000000000000000000000000000000000000012"}],"id":67}' http://localhost:8550/
|
||||
|
||||
type rwc struct {
|
||||
io.Reader
|
||||
io.Writer
|
||||
|
|
|
|||
Loading…
Reference in a new issue