From 82661011de8af19571d5d75f1b96397e0a144f86 Mon Sep 17 00:00:00 2001 From: Apisit Toompakdee Date: Thu, 3 May 2018 18:22:39 +0900 Subject: [PATCH] tests and more rpc methods --- neoutils/mobile_test.go | 12 ++++---- neoutils/neorpc/request.go | 9 ++++++ neoutils/neorpc/response.go | 38 +++++++++++++++++++++++++ neoutils/neorpc/rpc.go | 36 +++++++++++++++++++++++ neoutils/neorpc/rpc_test.go | 20 +++++++++++++ neoutils/neowallet_test.go | 2 +- neoutils/nep5.go | 2 +- neoutils/smartcontract/parser.go | 12 ++++++-- neoutils/smartcontract/scriptbuilder.go | 12 +++++++- neoutils/smartcontract_test.go | 5 ++-- neoutils/utils_test.go | 4 +-- 11 files changed, 137 insertions(+), 15 deletions(-) diff --git a/neoutils/mobile_test.go b/neoutils/mobile_test.go index 3deeb4b..041eac7 100644 --- a/neoutils/mobile_test.go +++ b/neoutils/mobile_test.go @@ -9,25 +9,25 @@ import ( ) func TestMintTokensFromMobile(t *testing.T) { - scriptHash := "a6f331f6d7d8b331a95ef8513c573e938c073c6b" + scriptHash := "0xf820184470f1a5f38fa4ecc8db746336b371bda5" //both of these are whitelisted //ALL PRIVATE NET TEST ADDRESSES // wif := "KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr" // contract owner AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y - wif := "L2W3eBvPYMUaxDZGEb395HZf26tLPZgU5qN351HpyVSAG1DWgDtx" // Adm9ER3UwdJfimFtFhHq1L5MQ5gxLLTUes - // wif := "L5h6cTh45egotcxFZ2rkF1gv7rLxx9rScfuja9kEVEE9mEj9Uwtv" //AQaZPqcv9Kg2x1eSrF8UBYXLK4WQoTSLH5 + // wif := "L2W3eBvPYMUaxDZGEb395HZf26tLPZgU5qN351HpyVSAG1DWgDtx" // AQmq2yU7DupE4VddmEoweKiJFyGhAAEZeH + wif := "L5h6cTh45egotcxFZ2rkF1gv7rLxx9rScfuja9kEVEE9mEj9Uwtv" //AQaZPqcv9Kg2x1eSrF8UBYXLK4WQoTSLH5 //this addresss is not whitelisted // wif := "L5gmcoaetU6YGSzg4wNqvKBEEAfwCAxWseuL3pxvLvEMZB9WyUYp" wallet, _ := neoutils.GenerateFromWIF(wif) - log.Printf("address = %v\n address hash = %v %x", wallet.Address, neoutils.NEOAddressToScriptHash(wallet.Address), wallet.HashedSignature) + log.Printf("address = %v\n address hash = %x", wallet.Address, wallet.HashedSignature) neo := string(smartcontract.NEO) // gas := string(smartcontract.GAS) - amount := float64(1) + amount := float64(2) remark := "o3x" utxoEndpoint := "http://localhost:5000/" - networkFeeAmountInGAS := float64(0.001) + networkFeeAmountInGAS := float64(0.0011) tx, err := neoutils.MintTokensRawTransactionMobile(utxoEndpoint, scriptHash, wif, neo, amount, remark, networkFeeAmountInGAS) if err != nil { diff --git a/neoutils/neorpc/request.go b/neoutils/neorpc/request.go index 28a62fe..d0cfa69 100644 --- a/neoutils/neorpc/request.go +++ b/neoutils/neorpc/request.go @@ -15,3 +15,12 @@ func NewRequest(method string, params []interface{}) JSONRPCRequest { ID: 1, } } + +type InvokeFunctionStackArg struct { + Type string `json:"type"` + Value string `json:"value"` +} + +func NewInvokeFunctionStackByteArray(value string) InvokeFunctionStackArg { + return InvokeFunctionStackArg{Type: "ByteArray", Value: value} +} diff --git a/neoutils/neorpc/response.go b/neoutils/neorpc/response.go index 7ea63c4..a791088 100644 --- a/neoutils/neorpc/response.go +++ b/neoutils/neorpc/response.go @@ -123,3 +123,41 @@ type GetBlockResult struct { Confirmations int `json:"confirmations"` Nextblockhash string `json:"nextblockhash"` } + +type GetAccountStateResponse struct { + JSONRPCResponse + *ErrorResponse //optional + Result GetAccountStateResult `json:"result"` +} + +type GetAccountStateResult struct { + Version int `json:"version"` + ScriptHash string `json:"script_hash"` + Frozen bool `json:"frozen"` + Votes []interface{} `json:"votes"` + Balances []GetAccountStateBalance `json:"balances"` +} + +type GetAccountStateBalance struct { + Asset string `json:"asset"` + Value string `json:"value"` +} + +type TokenBalanceResponse struct { + JSONRPCResponse + *ErrorResponse //optional + Result TokenBalanceResult `json:"result"` +} + +type InvokeFunctionStackResult struct { + Type string `json:"type"` + Value string `json:"value"` +} + +type TokenBalanceResult struct { + Script string `json:"script"` + State string `json:"state"` + GasConsumed string `json:"gas_consumed"` + Stack []InvokeFunctionStackResult `json:"stack"` + Tx string `json:"tx"` +} diff --git a/neoutils/neorpc/rpc.go b/neoutils/neorpc/rpc.go index e989c0d..d4a4597 100644 --- a/neoutils/neorpc/rpc.go +++ b/neoutils/neorpc/rpc.go @@ -3,8 +3,11 @@ package neorpc import ( "bytes" "encoding/json" + "fmt" "net/http" "net/url" + + "github.com/apisit/btckeygenie/btckey" ) type NEORPCInterface interface { @@ -15,6 +18,9 @@ type NEORPCInterface interface { GetBlockCount() GetBlockCountResponse GetBlock(blockHash string) GetBlockResponse GetBlockByIndex(index int) GetBlockResponse + GetAccountState(address string) GetAccountStateResponse + + GetTokenBalance(tokenHash string, adddress string) TokenBalanceResponse } type NEORPCClient struct { @@ -113,3 +119,33 @@ func (n *NEORPCClient) GetBlockCount() GetBlockCountResponse { } return response } + +func (n *NEORPCClient) GetAccountState(address string) GetAccountStateResponse { + response := GetAccountStateResponse{} + params := []interface{}{address, 1} + err := n.makeRequest("getaccountstate", params, &response) + if err != nil { + return response + } + return response +} + +func (n *NEORPCClient) GetTokenBalance(tokenHash string, neoAddress string) TokenBalanceResponse { + response := TokenBalanceResponse{} + args := []interface{}{} + + v, b, _ := btckey.B58checkdecode(neoAddress) + if v != 0x17 { + return TokenBalanceResponse{} + } + adddressScriptHash := fmt.Sprintf("%x", b) + input := NewInvokeFunctionStackByteArray(adddressScriptHash) + args = append(args, input) + + params := []interface{}{tokenHash, "balanceOf", args} + err := n.makeRequest("invokefunction", params, &response) + if err != nil { + return response + } + return response +} diff --git a/neoutils/neorpc/rpc_test.go b/neoutils/neorpc/rpc_test.go index 6086b02..116feb8 100644 --- a/neoutils/neorpc/rpc_test.go +++ b/neoutils/neorpc/rpc_test.go @@ -75,3 +75,23 @@ func TestGetBlockCount(t *testing.T) { result := client.GetBlockCount() log.Printf("%+v", result.Result) } + +func TestGetAccountState(t *testing.T) { + client := neorpc.NewClient("http://seed2.o3node.org:10332") + if client == nil { + t.Fail() + } + + result := client.GetAccountState("AdSBfV9kMmN2Q3xMYSbU33HWQA1dCc9CV3") + log.Printf("%+v", result.Result) +} + +func TestGetTokenBalance(t *testing.T) { + client := neorpc.NewClient("http://localhost:30333") + if client == nil { + t.Fail() + } + + result := client.GetTokenBalance("0xf820184470f1a5f38fa4ecc8db746336b371bda5", "AQmq2yU7DupE4VddmEoweKiJFyGhAAEZeH") + log.Printf("%+v", result.Result) +} diff --git a/neoutils/neowallet_test.go b/neoutils/neowallet_test.go index 4d34515..14d484f 100644 --- a/neoutils/neowallet_test.go +++ b/neoutils/neowallet_test.go @@ -28,7 +28,7 @@ func TestGenKey(t *testing.T) { } func TestGenFromWIF(t *testing.T) { - wif := "KzULqzStT2tseGnqogXnTLG5NCT1YXa3F9Wp1Kdv9xMxFhvV6H2A" + wif := "" wallet, err := neoutils.GenerateFromWIF(wif) if err != nil { log.Printf("%+v", err) diff --git a/neoutils/nep5.go b/neoutils/nep5.go index f5eeaad..56b62cb 100644 --- a/neoutils/nep5.go +++ b/neoutils/nep5.go @@ -113,7 +113,7 @@ func (n *NEP5) TransferNEP5RawTransaction(wallet Wallet, toAddress smartcontract func (n *NEP5) MintTokensRawTransaction(wallet Wallet, assetToSend smartcontract.NativeAsset, amount float64, unspent smartcontract.Unspent, remark string) ([]byte, string, error) { - needVerification := false + needVerification := true log.Printf("needVerification = %v", needVerification) operation := "mintTokens" args := []interface{}{} diff --git a/neoutils/smartcontract/parser.go b/neoutils/smartcontract/parser.go index 92616c0..e3691c4 100644 --- a/neoutils/smartcontract/parser.go +++ b/neoutils/smartcontract/parser.go @@ -150,8 +150,16 @@ func (p *Parser) FindScriptHashes() ([]string, error) { } reversed := reverseBytes(b) splittedByAppCall := bytes.Split(reversed, []byte{byte(APPCALL)}) - for _, v := range splittedByAppCall { - if len(v) >= 20 { + //when splitted, the left side is the one that has the proper script hash + for index, v := range splittedByAppCall { + //even index is the left side + + //we skip the odd index + if index%2 != 0 { + continue + } + + if len(v) >= scripthashLength { startIndex := len(v) - scripthashLength endIndex := len(v) s := reversed[startIndex:endIndex] diff --git a/neoutils/smartcontract/scriptbuilder.go b/neoutils/smartcontract/scriptbuilder.go index 1016cd3..e97ed30 100644 --- a/neoutils/smartcontract/scriptbuilder.go +++ b/neoutils/smartcontract/scriptbuilder.go @@ -254,8 +254,18 @@ func (s *ScriptBuilder) pushData(data interface{}) error { return nil } +func has0xPrefix(input string) bool { + return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X') +} + func NewScriptHash(hexString string) (ScriptHash, error) { - b, err := hex.DecodeString(hexString) + //check if the scripthash is prefixed with 0x. if so, trim it out. + trimmed0x := hexString + if has0xPrefix(hexString) == true { + trimmed0x = hexString[2:] + } + log.Printf("script hash = %v", trimmed0x) + b, err := hex.DecodeString(trimmed0x) if err != nil { return nil, err } diff --git a/neoutils/smartcontract_test.go b/neoutils/smartcontract_test.go index 880730c..caa73a8 100644 --- a/neoutils/smartcontract_test.go +++ b/neoutils/smartcontract_test.go @@ -8,8 +8,6 @@ import ( "github.com/o3labs/neo-utils/neoutils/smartcontract" ) -var validSmartContract = neoutils.UseSmartContract("b7c1f850a025e34455e7e98c588c784385077fb1") - func TestInvalidSmartContractStruct(t *testing.T) { sc := neoutils.UseSmartContract("ce575ae1bb6153330d2") if sc != nil { @@ -71,6 +69,7 @@ func UTXODataForSmartContract() smartcontract.Unspent { } func TestInvokeFunctionRawTransaction(t *testing.T) { + var validSmartContract = neoutils.UseSmartContract("b7c1f850a025e34455e7e98c588c784385077fb1") wif := "KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr" privateNetwallet, err := neoutils.GenerateFromWIF(wif) @@ -100,6 +99,8 @@ func TestInvokeFunctionRawTransaction(t *testing.T) { } func TestGenerateInvokeTransferNEP5Token(t *testing.T) { + var validSmartContract = neoutils.UseSmartContract("b7c1f850a025e34455e7e98c588c784385077fb1") + wif := "KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr" privateNetwallet, err := neoutils.GenerateFromWIF(wif) if err != nil { diff --git a/neoutils/utils_test.go b/neoutils/utils_test.go index b390a6f..853d8c4 100644 --- a/neoutils/utils_test.go +++ b/neoutils/utils_test.go @@ -33,7 +33,7 @@ func TestScriptHashToNEOAddress(t *testing.T) { } func TestNEOAddressToScriptHash(t *testing.T) { - hash := NEOAddressToScriptHash("ASH41gtWftHvhuYhZz1jj7ee7z9vp9D9wk") + hash := NEOAddressToScriptHash("AQmq2yU7DupE4VddmEoweKiJFyGhAAEZeH") b, _ := hex.DecodeString(hash) log.Printf("%x %x", ReverseBytes(b), b) } @@ -53,7 +53,7 @@ func TestValidateNEOAddressInvalidAddress(t *testing.T) { } func TestConverting(t *testing.T) { - hex := "001175f11e" + hex := "00e8764817" //hex := "005c7c875e" = 405991873536 value := ConvertByteArrayToBigInt(hex)