From f77508ae8489f58f913752adaab1ce49d072f51f Mon Sep 17 00:00:00 2001 From: Minh Doan Date: Mon, 3 Jun 2019 15:26:49 -0700 Subject: [PATCH] clean up smart contract code --- node/contract_test.go | 36 ------- node/demo_contract.go | 215 ------------------------------------- node/node.go | 10 +- node/puzzle_contract.go | 228 ---------------------------------------- 4 files changed, 2 insertions(+), 487 deletions(-) delete mode 100644 node/contract_test.go delete mode 100644 node/demo_contract.go delete mode 100644 node/puzzle_contract.go diff --git a/node/contract_test.go b/node/contract_test.go deleted file mode 100644 index 92c624bf1..000000000 --- a/node/contract_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package node - -import ( - "testing" - - "github.com/harmony-one/harmony/crypto/bls" - - "github.com/harmony-one/harmony/consensus" - "github.com/harmony-one/harmony/internal/utils" - "github.com/harmony-one/harmony/p2p" - "github.com/harmony-one/harmony/p2p/p2pimpl" -) - -func prepareNode(t *testing.T) *Node { - pubKey := bls.RandPrivateKey().GetPublicKey() - leader := p2p.Peer{IP: "127.0.0.1", Port: "8882", ConsensusPubKey: pubKey} - priKey, _, _ := utils.GenKeyP2P("127.0.0.1", "9902") - host, err := p2pimpl.NewHost(&leader, priKey) - if err != nil { - t.Fatalf("newhost failure: %v", err) - } - consensus, err := consensus.New(host, 0, leader, nil) - if err != nil { - t.Fatalf("Cannot craeate consensus: %v", err) - } - return New(host, consensus, testDBFactory, false) - -} - -func TestAddLotteryContract(t *testing.T) { - node := prepareNode(t) - node.AddLotteryContract() - if len(node.DemoContractAddress) == 0 { - t.Error("Can not create demo contract") - } -} diff --git a/node/demo_contract.go b/node/demo_contract.go deleted file mode 100644 index b55e4ebee..000000000 --- a/node/demo_contract.go +++ /dev/null @@ -1,215 +0,0 @@ -package node - -import ( - "fmt" - "math" - "math/big" - "os" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/params" - "github.com/harmony-one/harmony/contracts" - "github.com/harmony-one/harmony/core/types" - "github.com/harmony-one/harmony/internal/utils" - contract_constants "github.com/harmony-one/harmony/internal/utils/contract" -) - -// Constants for lottery. -const ( - Enter = "enter" - PickWinner = "pickWinner" - GetPlayers = "getPlayers" - PuzzleFund = 100000000 -) - -// AddLotteryContract adds the demo lottery contract the genesis block. -func (node *Node) AddLotteryContract() { - // Add a lottery demo contract. - priKey, err := crypto.HexToECDSA(contract_constants.DemoAccounts[0].Private) - if err != nil { - utils.GetLogInstance().Error("Error when creating private key for demo contract") - // Exit here to recognize the coding working. - // Basically we will remove this logic when launching so it's fine for now. - os.Exit(1) - } - - dataEnc := common.FromHex(contracts.LotteryBin) - // Unsigned transaction to avoid the case of transaction address. - - contractFunds := big.NewInt(0) - contractFunds = contractFunds.Mul(contractFunds, big.NewInt(params.Ether)) - demoContract, _ := types.SignTx( - types.NewContractCreation(uint64(0), node.Consensus.ShardID, contractFunds, params.TxGasContractCreation*10, nil, dataEnc), - types.HomesteadSigner{}, - priKey) - node.DemoContractAddress = crypto.CreateAddress(crypto.PubkeyToAddress(priKey.PublicKey), uint64(0)) - node.LotteryManagerPrivateKey = priKey - node.addPendingTransactions(types.Transactions{demoContract}) -} - -// CreateTransactionForEnterMethod generates transaction for enter method and add it into pending tx list. -func (node *Node) CreateTransactionForEnterMethod(amount int64, priKey string) error { - var err error - toAddress := node.DemoContractAddress - - abi, err := abi.JSON(strings.NewReader(contracts.LotteryABI)) - if err != nil { - utils.GetLogInstance().Error("Failed to generate staking contract's ABI", "error", err) - return err - } - bytesData, err := abi.Pack(Enter) - if err != nil { - utils.GetLogInstance().Error("Failed to generate ABI function bytes data", "error", err) - return err - } - - key, err := crypto.HexToECDSA(priKey) - nonce := node.GetNonceOfAddress(crypto.PubkeyToAddress(key.PublicKey)) - Amount := big.NewInt(amount) - Amount = Amount.Mul(Amount, big.NewInt(params.Ether)) - tx := types.NewTransaction( - nonce, - toAddress, - node.NodeConfig.ShardID, - Amount, - params.TxGas*10, - nil, - bytesData, - ) - - if err != nil { - utils.GetLogInstance().Error("Failed to get private key", "error", err) - return err - } - if signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, key); err == nil { - node.addPendingTransactions(types.Transactions{signedTx}) - return nil - } - utils.GetLogInstance().Error("Unable to call enter method", "error", err) - return err -} - -// GetResultDirectly get current players and their balances, not from smart contract. -func (node *Node) GetResultDirectly(priKey string) (players []string, balances []*big.Int) { - for _, account := range contract_constants.DemoAccounts { - players = append(players, account.Private) - key, err := crypto.HexToECDSA(account.Private) - if err != nil { - utils.GetLogInstance().Error("Error when HexToECDSA") - } - address := crypto.PubkeyToAddress(key.PublicKey) - balance, err := node.GetBalanceOfAddress(address) - balances = append(balances, balance) - } - return players, balances -} - -// GenerateResultDirectly get current players and their balances, not from smart contract. -func (node *Node) GenerateResultDirectly(addresses []common.Address) (players []string, balances []*big.Int) { - for _, address := range addresses { - players = append(players, address.String()) - balance, _ := node.GetBalanceOfAddress(address) - balances = append(balances, balance) - } - fmt.Println("generate result", players, balances) - return players, balances -} - -// GetResult get current players and their balances. -func (node *Node) GetResult(priKey string) (players []string, balances []*big.Int) { - // TODO(minhdoan): get result from smart contract is current not working. Fix it later. - abi, err := abi.JSON(strings.NewReader(contracts.LotteryABI)) - if err != nil { - utils.GetLogInstance().Error("Failed to generate staking contract's ABI", "error", err) - } - bytesData, err := abi.Pack("getPlayers") - if err != nil { - utils.GetLogInstance().Error("Failed to generate ABI function bytes data", "error", err) - } - - demoContractAddress := node.DemoContractAddress - key, err := crypto.HexToECDSA(priKey) - if err != nil { - utils.GetLogInstance().Error("Failed to parse private key", "error", err) - } - - nonce := node.GetNonceOfAddress(crypto.PubkeyToAddress(key.PublicKey)) - - tx := types.NewTransaction( - nonce, - demoContractAddress, - node.NodeConfig.ShardID, - nil, - math.MaxUint64, - nil, - bytesData, - ) - signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, key) - if err != nil { - utils.GetLogInstance().Error("Failed to sign contract call tx", "error", err) - return nil, nil - } - output, err := node.ContractCaller.CallContract(signedTx) - if err != nil { - utils.GetLogInstance().Error("Failed to call staking contract", "error", err) - return nil, nil - } - - ret := []common.Address{} - err = abi.Unpack(&ret, "getPlayers", output) - - if err != nil { - utils.GetLogInstance().Error("Failed to unpack getPlayers", "error", err) - return nil, nil - } - utils.GetLogInstance().Info("get result: ", "ret", ret) - fmt.Println("get result called:", ret) - return node.GenerateResultDirectly(ret) -} - -// CreateTransactionForPickWinner generates transaction for enter method and add it into pending tx list. -func (node *Node) CreateTransactionForPickWinner() error { - var err error - toAddress := node.DemoContractAddress - - abi, err := abi.JSON(strings.NewReader(contracts.LotteryABI)) - if err != nil { - utils.GetLogInstance().Error("Failed to generate staking contract's ABI", "error", err) - return err - } - bytesData, err := abi.Pack(PickWinner) - if err != nil { - utils.GetLogInstance().Error("Failed to generate ABI function bytes data", "error", err) - return err - } - - key := node.LotteryManagerPrivateKey - if key == nil { - return fmt.Errorf("LotterManagerPrivateKey is nil") - } - nonce := node.GetNonceOfAddress(crypto.PubkeyToAddress(key.PublicKey)) - Amount := big.NewInt(0) - tx := types.NewTransaction( - nonce, - toAddress, - node.NodeConfig.ShardID, - Amount, - params.TxGas*1000, - nil, - bytesData, - ) - - if err != nil { - utils.GetLogInstance().Error("Failed to get private key", "error", err) - return err - } - if signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, key); err == nil { - node.addPendingTransactions(types.Transactions{signedTx}) - return nil - } - utils.GetLogInstance().Error("Unable to call enter method", "error", err) - return err -} diff --git a/node/node.go b/node/node.go index 82960c8d1..98227bdc4 100644 --- a/node/node.go +++ b/node/node.go @@ -15,7 +15,6 @@ import ( "github.com/harmony-one/harmony/accounts" "github.com/harmony-one/harmony/api/client" - clientService "github.com/harmony-one/harmony/api/client/service" msg_pb "github.com/harmony-one/harmony/api/proto/message" "github.com/harmony-one/harmony/api/service" "github.com/harmony-one/harmony/api/service/syncing" @@ -69,10 +68,8 @@ func (state State) String() string { } const ( - // ClientServicePortDiff is the positive port diff for client service - ClientServicePortDiff = 5555 - maxBroadcastNodes = 10 // broadcast at most maxBroadcastNodes peers that need in sync - broadcastTimeout int64 = 3 * 60 * 1000000000 // 3 mins + maxBroadcastNodes = 10 // broadcast at most maxBroadcastNodes peers that need in sync + broadcastTimeout int64 = 3 * 60 * 1000000000 // 3 mins //SyncIDLength is the length of bytes for syncID SyncIDLength = 20 ) @@ -115,9 +112,6 @@ type Node struct { Worker *worker.Worker BeaconWorker *worker.Worker // worker for beacon chain - // Client server (for wallet requests) - clientServer *clientService.Server - // Syncing component. syncID [SyncIDLength]byte // a unique ID for the node during the state syncing process with peers downloaderServer *downloader.Server diff --git a/node/puzzle_contract.go b/node/puzzle_contract.go deleted file mode 100644 index e20735a11..000000000 --- a/node/puzzle_contract.go +++ /dev/null @@ -1,228 +0,0 @@ -package node - -import ( - "fmt" - "math/big" - "os" - "strings" - "sync/atomic" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/params" - "github.com/harmony-one/harmony/contracts" - "github.com/harmony-one/harmony/core/types" - "github.com/harmony-one/harmony/internal/utils" - contract_constants "github.com/harmony-one/harmony/internal/utils/contract" -) - -// Constants for puzzle. -const ( - Play = "play" - Payout = "payout" - EndGame = "endGame" -) - -// OneEther is one ether -var OneEther = big.NewInt(params.Ether) - -// AddPuzzleContract adds the demo puzzle contract the genesis block. -func (node *Node) AddPuzzleContract() { - // Add a puzzle demo contract. - priKey, err := crypto.HexToECDSA(contract_constants.PuzzleAccounts[0].Private) - if err != nil { - utils.GetLogInstance().Error("Error when creating private key for puzzle demo contract") - // Exit here to recognize the coding working. - // Basically we will remove this logic when launching so it's fine for now. - os.Exit(1) - } - - dataEnc := common.FromHex(contracts.PuzzleBin) - // Unsigned transaction to avoid the case of transaction address. - - contractFunds := big.NewInt(PuzzleFund) - contractFunds = contractFunds.Mul(contractFunds, big.NewInt(params.Ether)) - demoContract, _ := types.SignTx( - types.NewContractCreation(uint64(0), node.Consensus.ShardID, contractFunds, params.TxGasContractCreation*1000, nil, dataEnc), - types.HomesteadSigner{}, - priKey) - node.PuzzleContractAddress = crypto.CreateAddress(crypto.PubkeyToAddress(priKey.PublicKey), uint64(0)) - node.PuzzleManagerPrivateKey = priKey - node.addPendingTransactions(types.Transactions{demoContract}) -} - -// CreateTransactionForPlayMethod generates transaction for play method and add it into pending tx list. -func (node *Node) CreateTransactionForPlayMethod(priKey string, amount int64) (string, error) { - var err error - toAddress := node.PuzzleContractAddress - abi, err := abi.JSON(strings.NewReader(contracts.PuzzleABI)) - if err != nil { - utils.GetLogInstance().Error("puzzle-play: Failed to generate staking contract's ABI", "error", err) - return "", err - } - bytesData, err := abi.Pack(Play) - if err != nil { - utils.GetLogInstance().Error("puzzle-play: Failed to generate ABI function bytes data", "error", err) - return "", err - } - - Stake := big.NewInt(0) - Stake = Stake.Mul(OneEther, big.NewInt(amount)) - - key, err := crypto.HexToECDSA(priKey) - if err != nil { - utils.GetLogInstance().Error("Failed to parse private key", "error", err) - return "", err - } - address := crypto.PubkeyToAddress(key.PublicKey) - balance, err := node.GetBalanceOfAddress(address) - if err != nil { - utils.GetLogInstance().Error("puzzle-play: can not get address", "error", err) - return "", err - } else if balance.Cmp(Stake) == -1 { - utils.GetLogInstance().Error("puzzle-play: insufficient fund", "error", err, "stake", Stake, "balance", balance) - return "", ErrPuzzleInsufficientFund - } - nonce := node.GetAndIncreaseAddressNonce(address) - tx := types.NewTransaction( - nonce, - toAddress, - node.NodeConfig.ShardID, - Stake, - params.TxGas*100, - nil, - bytesData, - ) - - if err != nil { - utils.GetLogInstance().Error("puzzle-play: Failed to get private key", "error", err) - return "", err - } - if signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, key); err == nil { - node.addPendingTransactions(types.Transactions{signedTx}) - return signedTx.Hash().Hex(), nil - } - utils.GetLogInstance().Error("puzzle-play: Unable to call enter method", "error", err) - return "", err -} - -// CreateTransactionForPayoutMethod generates transaction for payout method and add it into pending tx list. -func (node *Node) CreateTransactionForPayoutMethod(priKey string, level int, sequence string) (string, error) { - var err error - toAddress := node.PuzzleContractAddress - - abi, err := abi.JSON(strings.NewReader(contracts.PuzzleABI)) - if err != nil { - utils.GetLogInstance().Error("Failed to generate staking contract's ABI", "error", err) - return "", err - } - - key, err := crypto.HexToECDSA(priKey) - if err != nil { - utils.GetLogInstance().Error("Failed to parse private key", "error", err) - return "", err - } - address := crypto.PubkeyToAddress(key.PublicKey) - - // add params for address payable player, uint8 new_level, steps string - fmt.Println("Payout: address", address) - bytesData, err := abi.Pack(Payout, address, big.NewInt(int64(level)), sequence) - if err != nil { - utils.GetLogInstance().Error("Failed to generate ABI function bytes data", "error", err) - return "", err - } - - if key == nil { - return "", fmt.Errorf("user key is nil") - } - nonce := node.GetAndIncreaseAddressNonce(address) - Amount := big.NewInt(0) - tx := types.NewTransaction( - nonce, - toAddress, - node.NodeConfig.ShardID, - Amount, - params.TxGas*10, - nil, - bytesData, - ) - - if err != nil { - utils.GetLogInstance().Error("Failed to get private key", "error", err) - return "", err - } - if signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, key); err == nil { - node.addPendingTransactions(types.Transactions{signedTx}) - return signedTx.Hash().Hex(), nil - } - utils.GetLogInstance().Error("Unable to call enter method", "error", err) - return "", err -} - -// CreateTransactionForEndMethod generates transaction for endGame method and add it into pending tx list. -func (node *Node) CreateTransactionForEndMethod(priKey string) (string, error) { - var err error - toAddress := node.PuzzleContractAddress - - abi, err := abi.JSON(strings.NewReader(contracts.PuzzleABI)) - if err != nil { - utils.GetLogInstance().Error("Failed to generate staking contract's ABI", "error", err) - return "", err - } - key, err := crypto.HexToECDSA(priKey) - if err != nil { - utils.GetLogInstance().Error("Failed to parse private key", "error", err) - return "", err - } - address := crypto.PubkeyToAddress(key.PublicKey) - - // add params for address payable player, uint8 new_level, steps string - fmt.Println("EndGame: address", address) - bytesData, err := abi.Pack(EndGame, address) - if err != nil { - utils.GetLogInstance().Error("Failed to generate ABI function bytes data", "error", err) - return "", err - } - - if key == nil { - return "", fmt.Errorf("user key is nil") - } - nonce := node.GetAndIncreaseAddressNonce(address) - Amount := big.NewInt(0) - tx := types.NewTransaction( - nonce, - toAddress, - node.NodeConfig.ShardID, - Amount, - params.TxGas*10, - nil, - bytesData, - ) - - if err != nil { - utils.GetLogInstance().Error("Failed to get private key", "error", err) - return "", err - } - if signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, key); err == nil { - node.addPendingTransactions(types.Transactions{signedTx}) - return signedTx.Hash().Hex(), nil - } - utils.GetLogInstance().Error("Unable to call enter method", "error", err) - return "", err -} - -// GetAndIncreaseAddressNonce get and increase the address's nonce -func (node *Node) GetAndIncreaseAddressNonce(address common.Address) uint64 { - if value, ok := node.AddressNonce.Load(address); ok { - n, ok := value.(uint64) - if !ok { - return 0 - } - nonce := atomic.AddUint64(&n, 1) - return nonce - 1 - } - nonce := node.GetNonceOfAddress(address) + 1 - node.AddressNonce.Store(address, nonce) - return nonce - 1 -}