The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
woop/node/demo_contract.go

197 lines
6.3 KiB

package node
// CreateTransactionForEnterMethod creates transaction to call enter method of lottery contract.
import (
"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"
)
// 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,
0,
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)
balances = append(balances, node.GetBalanceOfAddress(address))
}
return players, balances
}
// GetResult get current players and their balances.
func (node *Node) GetResult(priKey string) (players []string, balances []*big.Int) {
return node.GetResultDirectly(priKey)
// 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)
// nonce := node.GetNonceOfAddress(crypto.PubkeyToAddress(key.PublicKey))
// tx := types.NewTransaction(
// nonce,
// demoContractAddress,
// 0,
// 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 := &structs.PlayersInfo{}
// err = abi.Unpack(ret, "getPlayers", output)
// if err != nil {
// utils.GetLogInstance().Error("Failed to unpack stake info", "error", err)
// return nil, nil
// }
// for _, player := range ret.Players {
// players = append(players, player.String())
// }
// balances = ret.Balances
// return players, balances
}
// 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
nonce := node.GetNonceOfAddress(crypto.PubkeyToAddress(key.PublicKey))
Amount := big.NewInt(0)
tx := types.NewTransaction(
nonce,
toAddress,
0,
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
}