diff --git a/account/wallet_test.go b/account/wallet_test.go index 4f11284..4eb40a8 100644 --- a/account/wallet_test.go +++ b/account/wallet_test.go @@ -29,6 +29,37 @@ import ( "testing" ) +func TestPayload(t *testing.T) { + if os.Getenv("CI") != "" { + t.Skip("Skipping testing in CI environment") + } + wallet := NewWallet() + wallet.AddByPrivateKey("e19d05c5452598e24caad4a0d85a49146f7be089515c905ae6a19e8a578a6930") + provider := provider2.NewProvider("https://dev-api.zilliqa.com/") + + gasPrice, err := provider.GetMinimumGasPrice() + assert.Nil(t, err, err) + + tx := &transaction.Transaction{ + Version: strconv.FormatInt(int64(util.Pack(333, 1)), 10), + SenderPubKey: "0246E7178DC8253201101E18FD6F6EB9972451D121FC57AA2A06DD5C111E58DC6A", + ToAddr: "4BAF5faDA8e5Db92C3d3242618c5B47133AE003C", + Amount: "10000000", + GasPrice: gasPrice, + GasLimit: "1", + Code: "", + Data: "", + Priority: false, + } + err2 := wallet.Sign(tx, *provider) + assert.Nil(t, err2, err2) + + pl := tx.ToTransactionPayload() + payloadJson, err3 := pl.ToJson() + assert.Nil(t, err3, err3) + fmt.Println(string(payloadJson)) +} + func TestWallet_SignWith(t *testing.T) { if os.Getenv("CI") != "" { t.Skip("Skipping testing in CI environment") @@ -69,10 +100,12 @@ func TestSendTransaction(t *testing.T) { Data: "", Priority: false, } - err2 := wallet.Sign(tx, *provider) assert.Nil(t, err2, err2) + h, _ := tx.Hash() + fmt.Println("local transaction hash: ", util.EncodeHex(h)) + rsp, err3 := provider.CreateTransaction(tx.ToTransactionPayload()) assert.Nil(t, err3, err3) assert.Nil(t, rsp.Error, rsp.Error) diff --git a/contract/contract.go b/contract/contract.go index 899db7c..1b330fb 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -164,7 +164,6 @@ func (c *Contract) Call(transition string, args []core.ContractValue, params Cal if err2 != nil { return tx, err2 } - rsp, err := c.Provider.CreateTransaction(tx.ToTransactionPayload()) if err != nil { diff --git a/contract/contract_test.go b/contract/contract_test.go index ecacfb2..40f83c4 100644 --- a/contract/contract_test.go +++ b/contract/contract_test.go @@ -113,7 +113,6 @@ func TestContract_Call(t *testing.T) { privateKey := "e19d05c5452598e24caad4a0d85a49146f7be089515c905ae6a19e8a578a6930" chainID := 333 msgVersion := 1 - publickKey := keytools.GetPublicKeyFromPrivateKey(util.DecodeHex(privateKey), true) address := keytools.GetAddressFromPublic(publickKey) pubkey := util.EncodeHex(publickKey) diff --git a/core/types.go b/core/types.go index 251e1ea..d46692e 100644 --- a/core/types.go +++ b/core/types.go @@ -140,10 +140,10 @@ type Transition struct { } type TransactionMessage struct { - Amount string `json:"_amount"` - Receipt string `json:"_receipt"` - Tag string `json:"_tag"` - Params []ContractValue `json:"params"` + Amount string `json:"_amount"` + Recipient string `json:"_recipient"` + Tag string `json:"_tag"` + Params []ContractValue `json:"params"` } type Transactions struct { diff --git a/provider/transaction_payload.go b/provider/transaction_payload.go index 530f01f..5e9f7b5 100644 --- a/provider/transaction_payload.go +++ b/provider/transaction_payload.go @@ -51,11 +51,11 @@ type Data struct { } type payload struct { - Version int `json:"version"` - Nonce int `json:"nonce"` - ToAddr string `json:"toAddr"` - Amount int64 `json:"amount"` - //PubKey string `json:"pubKey"` + Version int `json:"version"` + Nonce int `json:"nonce"` + ToAddr string `json:"toAddr"` + Amount int64 `json:"amount"` + PubKey string `json:"pubKey"` GasPrice int64 `json:"gasPrice"` GasLimit int64 `json:"gasLimit"` Code string `json:"code"` @@ -65,11 +65,11 @@ type payload struct { } type Init struct { - Version int `json:"version"` - Nonce int `json:"nonce"` - ToAddr string `json:"toAddr"` - Amount int64 `json:"amount"` - //PubKey string `json:"pubKey"` + Version int `json:"version"` + Nonce int `json:"nonce"` + ToAddr string `json:"toAddr"` + Amount int64 `json:"amount"` + PubKey string `json:"pubKey"` GasPrice int64 `json:"gasPrice"` GasLimit int64 `json:"gasLimit"` Code string `json:"code"` @@ -77,6 +77,19 @@ type Init struct { Signature string `json:"signature"` } +type Payment struct { + Version int `json:"version"` + Nonce int `json:"nonce"` + ToAddr string `json:"toAddr"` + Amount int64 `json:"amount"` + PubKey string `json:"pubKey"` + GasPrice int64 `json:"gasPrice"` + GasLimit int64 `json:"gasLimit"` + Code string `json:"code"` + Data string `json:"data"` + Signature string `json:"signature"` +} + func (pl *TransactionPayload) ToJson() ([]byte, error) { a, err := strconv.ParseInt(pl.Amount, 10, 64) if err != nil { @@ -93,6 +106,23 @@ func (pl *TransactionPayload) ToJson() ([]byte, error) { return nil, err3 } + if pl.Data == "" { + p := Payment{ + Version: pl.Version, + Nonce: pl.Nonce, + ToAddr: pl.ToAddr, + Amount: a, + PubKey: pl.PubKey, + GasPrice: price, + GasLimit: limit, + Code: pl.Code, + Data: "", + Signature: pl.Signature, + //Priority: pl.Priority, + } + return json.Marshal(&p) + } + originData := strings.TrimPrefix(pl.Data, `"`) originData = strings.TrimSuffix(originData, `"`) originData = strings.ReplaceAll(originData, "\\", "") @@ -106,11 +136,11 @@ func (pl *TransactionPayload) ToJson() ([]byte, error) { return nil, errors.New("wrong data") } else { p := Init{ - Version: pl.Version, - Nonce: pl.Nonce, - ToAddr: pl.ToAddr, - Amount: a, - //PubKey: pl.PubKey, + Version: pl.Version, + Nonce: pl.Nonce, + ToAddr: pl.ToAddr, + Amount: a, + PubKey: pl.PubKey, GasPrice: price, GasLimit: limit, Code: pl.Code, @@ -122,11 +152,11 @@ func (pl *TransactionPayload) ToJson() ([]byte, error) { } } else { p := payload{ - Version: pl.Version, - Nonce: pl.Nonce, - ToAddr: pl.ToAddr, - Amount: a, - //PubKey: pl.PubKey, + Version: pl.Version, + Nonce: pl.Nonce, + ToAddr: pl.ToAddr, + Amount: a, + PubKey: pl.PubKey, GasPrice: price, GasLimit: limit, Code: pl.Code, @@ -193,10 +223,10 @@ func NewFromMap(middle map[string]interface{}) (*TransactionPayload, error) { return nil, errors.New("parse payload json failed: limit") } - //pubkey, ok6 := middle["pubKey"].(string) - //if !ok6 { - // return nil, errors.New("parse payload json failed: public key") - //} + pubkey, ok6 := middle["pubKey"].(string) + if !ok6 { + return nil, errors.New("parse payload json failed: public key") + } code, ok7 := middle["code"].(string) if !ok7 { @@ -217,6 +247,8 @@ func NewFromMap(middle map[string]interface{}) (*TransactionPayload, error) { return nil, err } sd = string(s) + } else if reflect.TypeOf(d).Kind() == reflect.String { + sd = d.(string) } else { j, _ := json.Marshal(d) var data Data @@ -237,11 +269,11 @@ func NewFromMap(middle map[string]interface{}) (*TransactionPayload, error) { } return &TransactionPayload{ - Version: int(v), - Nonce: int(n), - ToAddr: toAddr.(string), - Amount: fmt.Sprintf("%.0f", amount), - //PubKey: pubkey, + Version: int(v), + Nonce: int(n), + ToAddr: toAddr.(string), + Amount: fmt.Sprintf("%.0f", amount), + PubKey: pubkey, GasPrice: fmt.Sprintf("%.0f", price), GasLimit: fmt.Sprintf("%.0f", limit), Code: code, diff --git a/provider/transaction_payload_test.go b/provider/transaction_payload_test.go index 08bafe7..2194d0b 100644 --- a/provider/transaction_payload_test.go +++ b/provider/transaction_payload_test.go @@ -2,71 +2,15 @@ package provider import ( "fmt" + "os" "testing" ) func TestNewFromJson(t *testing.T) { - data := []byte(`{ - "version": 65537, - "nonce": 1, - "toAddr": "0x0000000000000000000000000000000000000000", - "amount": 0, - "gasPrice": 10000000, - "gasLimit": 9000, - "code": "", - "data": [ - { - "vname": "_scilla_version", - "type": "Uint32", - "value": "0" - }, - { - "vname": "initial_owners", - "type": "List ByStr20", - "value": { - "constructor": "Cons", - "argtypes": [ - "ByStr20" - ], - "arguments": [ - "0x1234567890123456789012345678906784567890", - { - "constructor": "Cons", - "argtypes": [ - "ByStr20" - ], - "arguments": [ - "0xabcdeabcde123456786782345678901234567890", - { - "constructor": "Cons", - "argtypes": [ - "ByStr20" - ], - "arguments": [ - "0xffcdeabcde126786789012345678901234567890", - { - "constructor": "Nil", - "argtypes": [ - "ByStr20" - ], - "arguments": [] - } - ] - } - ] - } - ] - } - }, - { - "vname": "required_signatures", - "type": "Uint32", - "value": "2" - } - ], - "signature": "", - "pubKey": "" -}`) + if os.Getenv("CI") != "" { + t.Skip("Skipping testing in CI environment") + } + data := []byte(`{"version":21823489,"nonce":166471,"toAddr":"bd7198209529dC42320db4bC8508880BcD22a9f2","amount":0,"pubKey":"0246e7178dc8253201101e18fd6f6eb9972451d121fc57aa2a06dd5c111e58dc6a","gasPrice":1000000000,"gasLimit":1000,"code":"","data":{"_tag":"Transfer","params":[{"vname":"to","type":"ByStr20","value":"0x9bfec715a6bd658fcb62b0f8cc9bfa2ade71434a"},{"vname":"tokens","type":"Uint128","value":"10"}]},"signature":"e4ae77ba4534598a723a3792705dd7477ffef8a475da94388d1af0cd29b38a3737b64fbedc4eb72c66b28303ac1b0bb8c45a68da2d40d6def367cbf20e751747"}`) payload, err2 := NewFromJson(data) if err2 != nil { @@ -75,7 +19,6 @@ func TestNewFromJson(t *testing.T) { fmt.Println(payload) - data = []byte(`{"version":21823489,"nonce":959,"toAddr":"84eb5C96Bec8d29eDdFBe36865E9B7F26b816f0F","amount":0,"pubKey":"0246e7178dc8253201101e18fd6f6eb9972451d121fc57aa2a06dd5c111e58dc6a","gasPrice":1000000000,"gasLimit":10000,"code":"","data":{"_tag":"SubmitCustomMintTransaction","params":[{"vname":"proxyTokenContract","type":"ByStr20","value":"0x39550ab45d74cce5fef70e857c1326b2d9bee096"},{"vname":"to","type":"ByStr20","value":"0x39550ab45d74cce5fef70e857c1326b2d9bee096"},{"vname":"value","type":"Uint128","value":"10000000"}]},"signature":"c0dcffb4f5ef80b9e426c16fc1fb62b31356219deb84c5689ab6a73915ea962c0bc4d4a49985803cd1db8aabb6870e8c749003cab41246e17493767acc6cca90"}`) payload2, err3 := NewFromJson(data) if err3 != nil { t.Error(err3.Error()) @@ -101,7 +44,7 @@ func TestTransactionPayload_ToJson(t *testing.T) { GasPrice: "10000000", GasLimit: "9000", Code: "", - Data: "[{\"vname\":\"_scilla_version\",\"type\":\"Uint32\",\"value\":\"0\"},{\"vname\":\"initial_owners\",\"type\":\"List ByStr20\",\"value\":{\"constructor\":\"Cons\",\"argtypes\":[\"ByStr20\"],\"arguments\":[\"0x1234567890123456789012345678906784567890\",{\"constructor\":\"Cons\",\"argtypes\":[\"ByStr20\"],\"arguments\":[\"0xabcdeabcde123456786782345678901234567890\",{\"constructor\":\"Cons\",\"argtypes\":[\"ByStr20\"],\"arguments\":[\"0xffcdeabcde126786789012345678901234567890\",{\"constructor\":\"Nil\",\"argtypes\":[\"ByStr20\"],\"arguments\":[]}]}]}]}},{\"vname\":\"required_signatures\",\"type\":\"Uint32\",\"value\":\"2\"}]", + Data: "", Signature: "", //Priority: false, } @@ -112,7 +55,7 @@ func TestTransactionPayload_ToJson(t *testing.T) { } fmt.Println(string(data)) - expect := "{\"version\":65537,\"nonce\":1,\"toAddr\":\"0x0000000000000000000000000000000000000000\",\"amount\":0,\"gasPrice\":10000000,\"gasLimit\":9000,\"code\":\"\",\"data\":[{\"vname\":\"_scilla_version\",\"type\":\"Uint32\",\"value\":\"0\"},{\"vname\":\"initial_owners\",\"type\":\"List ByStr20\",\"value\":{\"constructor\":\"Cons\",\"argtypes\":[\"ByStr20\"],\"arguments\":[\"0x1234567890123456789012345678906784567890\",{\"constructor\":\"Cons\",\"argtypes\":[\"ByStr20\"],\"arguments\":[\"0xabcdeabcde123456786782345678901234567890\",{\"constructor\":\"Cons\",\"argtypes\":[\"ByStr20\"],\"arguments\":[\"0xffcdeabcde126786789012345678901234567890\",{\"constructor\":\"Nil\",\"argtypes\":[\"ByStr20\"],\"arguments\":[]}]}]}]}},{\"vname\":\"required_signatures\",\"type\":\"Uint32\",\"value\":\"2\"}],\"signature\":\"\"}" + expect := "{\"version\":65537,\"nonce\":1,\"toAddr\":\"0x0000000000000000000000000000000000000000\",\"amount\":0,\"pubKey\":\"\",\"gasPrice\":10000000,\"gasLimit\":9000,\"code\":\"\",\"data\":\"\",\"signature\":\"\"}" if len(string(data)) != len(expect) { t.Fail() } diff --git a/transaction/transaction.go b/transaction/transaction.go index e8050c4..3aba360 100644 --- a/transaction/transaction.go +++ b/transaction/transaction.go @@ -16,23 +16,75 @@ type Transaction core.Transaction func NewFromPayload(payload *provider.TransactionPayload) *Transaction { v := strconv.FormatInt(int64(payload.Version), 10) n := strconv.FormatInt(int64(payload.Nonce), 10) - return &Transaction{ - ID: "", - Version: v, - Nonce: n, - Amount: payload.Amount, - GasPrice: payload.GasPrice, - GasLimit: payload.GasLimit, - Signature: payload.Signature, - Receipt: core.TransactionReceipt{}, - SenderPubKey: payload.PubKey, - ToAddr: payload.ToAddr, - Code: payload.Code, - Data: payload.Data, - Status: 0, - ContractAddress: "", - Priority: payload.Priority, + var toAddr string + if payload.ToAddr == "0x0000000000000000000000000000000000000000" { + toAddr = "0x0000000000000000000000000000000000000000" + } else { + toAddr = "0x" + payload.ToAddr + } + if payload.Data == "" { + // payment + return &Transaction{ + ID: "", + Version: v, + Nonce: n, + Amount: payload.Amount, + GasPrice: payload.GasPrice, + GasLimit: payload.GasLimit, + Signature: payload.Signature, + Receipt: core.TransactionReceipt{}, + SenderPubKey: payload.PubKey, + ToAddr: toAddr, + Code: payload.Code, + Data: "", + Status: 0, + ContractAddress: "", + Priority: payload.Priority, + } + } else if strings.Contains(payload.Data, "_tag") { + // contract call + var data provider.Data + json.Unmarshal([]byte(payload.Data), &data) + return &Transaction{ + ID: "", + Version: v, + Nonce: n, + Amount: payload.Amount, + GasPrice: payload.GasPrice, + GasLimit: payload.GasLimit, + Signature: payload.Signature, + Receipt: core.TransactionReceipt{}, + SenderPubKey: payload.PubKey, + ToAddr: toAddr, + Code: payload.Code, + Data: data, + Status: 0, + ContractAddress: "", + Priority: payload.Priority, + } + } else { + // contract deployment + var data []provider.Value + json.Unmarshal([]byte(payload.Data), &data) + return &Transaction{ + ID: "", + Version: v, + Nonce: n, + Amount: payload.Amount, + GasPrice: payload.GasPrice, + GasLimit: payload.GasLimit, + Signature: payload.Signature, + Receipt: core.TransactionReceipt{}, + SenderPubKey: payload.PubKey, + ToAddr: toAddr, + Code: payload.Code, + Data: data, + Status: 0, + ContractAddress: "", + Priority: payload.Priority, + } } + } func (t *Transaction) toTransactionParam() TxParams { @@ -129,6 +181,15 @@ func (t *Transaction) Bytes() ([]byte, error) { } } +func (t *Transaction) Hash() ([]byte, error) { + bytes, err := t.Bytes() + if err != nil { + return nil, err + } + hash := util.Sha256(bytes) + return hash, nil +} + func (t *Transaction) isPending() bool { return t.Status == core.Pending } diff --git a/transaction/transaction_test.go b/transaction/transaction_test.go index 5ea5233..e0c3951 100644 --- a/transaction/transaction_test.go +++ b/transaction/transaction_test.go @@ -143,3 +143,23 @@ func TestNewFromPayload2(t *testing.T) { assert.Nil(t, err, err) t.Log(string(data)) } + +func TestNewFromPayload3(t *testing.T) { + data := []byte(`{ + "version": 65537, + "nonce": 1, + "toAddr": "0x0000000000000000000000000000000000000000", + "amount": 0, + "gasPrice": 10000000, + "gasLimit": 9000, + "code": "", + "data":"", + "signature": "", + "pubKey": "" +}`) + + payload, err2 := provider.NewFromJson(data) + assert.Nil(t, err2, err2) + tx := NewFromPayload(payload) + t.Log(tx) +}