Unverified Commit e44ba57b authored by vipwzw's avatar vipwzw Committed by GitHub

Merge pull request #1105 from zhengjunhe/exchange_order_0929

Exchange order 0929
parents e869c482 e09bf312
......@@ -387,6 +387,9 @@ ForkAutonomyEnableItem=0
[fork.sub.jsvm]
Enable=0
[fork.sub.evmxgo]
Enable=0
[fork.sub.issuance]
Enable=0
ForkIssuanceTableUpdate=0
......
proj := "build"
.PHONY: default build remote winset
SRC_CLI := 33cn/plugin/plugin/dapp/bridgevmxgo/boss4x
OUT := build
default: build
build:
@go build -o ${OUT}/boss4x
remote:
@go build -v -o ${OUT}/boss4x_remote -ldflags "-X ${SRC_CLI}/buildFlags.RPCAddr4Chain33=http://183.129.226.74:8901"
winset:
@CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o ${OUT}/boss4x.exe -ldflags "-X ${SRC_CLI}/buildFlags.RPCAddr4Chain33=http://183.129.226.74:8901"
clean:
@rm ${OUT}/*
package buildFlags
var RPCAddr4Chain33 string
var paraName string
package chain33
import (
"github.com/33cn/plugin/plugin/dapp/bridgevmxgo/boss4x/chain33/offline"
"github.com/spf13/cobra"
)
func Chain33Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "chain33",
Short: "deploy to chain33",
}
cmd.AddCommand(
offline.Boss4xOfflineCmd(),
)
return cmd
}
package offline
import (
"fmt"
"math/big"
"github.com/33cn/plugin/plugin/dapp/bridgevmxgo/contracts/generated"
ebTypes "github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer/types"
utilsRelayer "github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer/utils"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
"github.com/spf13/cobra"
)
/*
./boss4x chain33 offline set_offline_token -c 1MaP3rrwiLV1wrxPhDwAfHggtei1ByaKrP -s BTY -m 100000000000 -p 50 -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae --chainID 33
./boss4x chain33 offline send -f chain33_set_offline_token.txt
*/
func ConfigLockedTokenOfflineSaveCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "set_offline_token",
Short: "set config offline locked token",
Run: ConfigMultisignLockedTokenOfflineSave,
}
addConfigLockedTokenOfflineSaveFlags(cmd)
return cmd
}
func addConfigLockedTokenOfflineSaveFlags(cmd *cobra.Command) {
cmd.Flags().StringP("contract", "c", "", "bridgebank contract address")
_ = cmd.MarkFlagRequired("contract")
cmd.Flags().StringP("token", "t", "", "token addr")
cmd.Flags().StringP("symbol", "s", "", "token symbol")
_ = cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("threshold", "m", "0", "threshold")
_ = cmd.MarkFlagRequired("threshold")
cmd.Flags().Uint8P("percents", "p", 50, "percents")
cmd.Flags().StringP("key", "k", "", "the deployer private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func ConfigMultisignLockedTokenOfflineSave(cmd *cobra.Command, _ []string) {
contract, _ := cmd.Flags().GetString("contract")
token, _ := cmd.Flags().GetString("token")
symbol, _ := cmd.Flags().GetString("symbol")
threshold, _ := cmd.Flags().GetString("threshold")
percents, _ := cmd.Flags().GetUint8("percents")
bn := big.NewInt(1)
bn, _ = bn.SetString(utilsRelayer.TrimZeroAndDot(threshold), 10)
if token == "" || symbol == "BTY" {
token = ebTypes.BTYAddrChain33
}
parameter := fmt.Sprintf("configLockedTokenOfflineSave(%s,%s,%d,%d)", token, symbol, bn, percents)
_, packData, err := evmAbi.Pack(parameter, generated.BridgeBankABI, false)
if nil != err {
fmt.Println("configOfflineSaveAccount", "Failed to do abi.Pack due to:", err.Error())
return
}
callContractAndSignWrite(cmd, packData, contract, "chain33_set_offline_token")
}
package offline
import (
"fmt"
"github.com/33cn/plugin/plugin/dapp/bridgevmxgo/contracts/generated"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
"github.com/spf13/cobra"
)
/*
./boss4x chain33 offline set_offline_addr -a 16skyHQA4YPPnhrDSSpZnexDzasS8BNx1R -c 1QD5pHMKZ9QWiNb9AsH3G1aG3Hashye83o -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae --chainID 33
./boss4x chain33 offline send -f chain33_set_offline_addr.txt
*/
func ConfigOfflineSaveAccountCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "set_offline_addr",
Short: "save config offline account",
Run: ConfigMultisignOfflineSaveAccount, //配置账户
}
addConfigOfflineSaveAccountFlags(cmd)
return cmd
}
func addConfigOfflineSaveAccountFlags(cmd *cobra.Command) {
cmd.Flags().StringP("address", "a", "", "multisign address")
_ = cmd.MarkFlagRequired("address")
cmd.Flags().StringP("contract", "c", "", "bridgebank contract address")
_ = cmd.MarkFlagRequired("contract")
cmd.Flags().StringP("key", "k", "", "the deployer private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func ConfigMultisignOfflineSaveAccount(cmd *cobra.Command, _ []string) {
multisign, _ := cmd.Flags().GetString("address")
contract, _ := cmd.Flags().GetString("contract")
parameter := fmt.Sprintf("configOfflineSaveAccount(%s)", multisign)
_, packData, err := evmAbi.Pack(parameter, generated.BridgeBankABI, false)
if nil != err {
fmt.Println("configOfflineSaveAccount", "Failed to do abi.Pack due to:", err.Error())
return
}
callContractAndSignWrite(cmd, packData, contract, "chain33_set_offline_addr")
}
package offline
import (
"encoding/json"
"fmt"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/system/crypto/secp256k1"
"github.com/33cn/plugin/plugin/dapp/bridgevmxgo/contracts/generated"
erc20 "github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/erc20/generated"
"github.com/33cn/plugin/plugin/dapp/dex/utils"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/spf13/cobra"
)
/*
./boss4x chain33 offline create_erc20 -s YCC -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae -o 1N6HstkyLFS8QCeVfdvYxx1xoryXoJtvvZ --chainID 33
./boss4x chain33 offline send -f deployErc20YCCChain33.txt
./boss4x chain33 offline approve_erc20 -a 330000000000 -s 1JmWVu1GEdQYSN1opxS9C39aS4NvG57yTr -c 1998HqVnt4JUirhC9KL5V71xYU8cFRn82c -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae --chainID 33
./boss4x chain33 offline send -f approve_erc20.txt
./boss4x chain33 offline create_add_lock_list -c 1JmWVu1GEdQYSN1opxS9C39aS4NvG57yTr -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae -t 1998HqVnt4JUirhC9KL5V71xYU8cFRn82c --chainID 33 -s YCC
./boss4x chain33 offline send -f create_add_lock_list.txt
./boss4x chain33 offline create_bridge_token -c 1JmWVu1GEdQYSN1opxS9C39aS4NvG57yTr -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae -s YCC --chainID 33
./boss4x chain33 offline send -f create_bridge_token.txt
${Chain33Cli} evm abi call -a "${chain33BridgeBank}" -c "${chain33DeployAddr}" -b "getToken2address(YCC)"
./chain33-cli evm abi call -a 1JmWVu1GEdQYSN1opxS9C39aS4NvG57yTr -c 1N6HstkyLFS8QCeVfdvYxx1xoryXoJtvvZ -b 'getToken2address(YCC)'
*/
func CreateERC20Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create_erc20",
Short: "create erc20 contracts and sign, default 3300*1e8 to be minted",
Run: CreateERC20,
}
CreateERC20Flags(cmd)
return cmd
}
//CreateERC20Flags ...
func CreateERC20Flags(cmd *cobra.Command) {
cmd.Flags().StringP("key", "k", "", "the deployer private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().StringP("owner", "o", "", "owner address")
_ = cmd.MarkFlagRequired("owner")
cmd.Flags().StringP("symbol", "s", "", "token symbol")
_ = cmd.MarkFlagRequired("symbol")
cmd.Flags().Float64P("amount", "a", 0, "amount to be minted(optional),default to 3300*1e8")
}
func CreateERC20(cmd *cobra.Command, _ []string) {
symbol, _ := cmd.Flags().GetString("symbol")
owner, _ := cmd.Flags().GetString("owner")
amount, _ := cmd.Flags().GetFloat64("amount")
amountInt64 := int64(3300 * 1e8)
if 0 != int64(amount) {
amountInt64 = int64(amount)
}
privateKeyStr, _ := cmd.Flags().GetString("key")
var driver secp256k1.Driver
privateKeySli := common.FromHex(privateKeyStr)
privateKey, err := driver.PrivKeyFromBytes(privateKeySli)
if nil != err {
fmt.Println("Failed to do PrivKeyFromBytes")
return
}
fromAddr := address.PubKeyToAddress(privateKey.PubKey().Bytes())
from := common.Address{
Addr: fromAddr,
}
createPara := fmt.Sprintf("%s,%s,%s,%s", symbol, symbol, fmt.Sprintf("%d", amountInt64), owner)
content, txHash, err := utils.CreateContractAndSign(getTxInfo(cmd), erc20.ERC20Bin, erc20.ERC20ABI, createPara, "ERC20:"+symbol)
if nil != err {
fmt.Println("CreateContractAndSign erc20 fail")
return
}
newContractAddr := common.NewContractAddress(from, txHash).String()
Erc20Tx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy ERC20:" + symbol,
}
data, err := json.MarshalIndent(Erc20Tx, "", " ")
if err != nil {
fmt.Println("MarshalIndent error", err.Error())
return
}
fmt.Println(string(data))
var txs []*utils.Chain33OfflineTx
txs = append(txs, Erc20Tx)
fileName := fmt.Sprintf("deployErc20%sChain33.txt", symbol)
fmt.Printf("Write all the txs to file: %s \n", fileName)
utils.WriteToFileInJson(fileName, txs)
}
func ApproveErc20Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "approve_erc20",
Short: "approve erc20",
Run: ApproveErc20, //配置账户
}
addApproveErc20Flags(cmd)
return cmd
}
func addApproveErc20Flags(cmd *cobra.Command) {
cmd.Flags().StringP("approve", "s", "", "approve addr")
_ = cmd.MarkFlagRequired("approve")
cmd.Flags().Float64P("amount", "a", 0, "approve amount")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("contract", "c", "", "Erc20 contract address")
_ = cmd.MarkFlagRequired("contract")
cmd.Flags().StringP("key", "k", "", "the deployer private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func ApproveErc20(cmd *cobra.Command, _ []string) {
contract, _ := cmd.Flags().GetString("contract")
approve, _ := cmd.Flags().GetString("approve")
amount, _ := cmd.Flags().GetFloat64("amount")
parameter := fmt.Sprintf("approve(%s,%d)", approve, int64(amount))
_, packData, err := evmAbi.Pack(parameter, generated.BridgeTokenABI, false)
if nil != err {
fmt.Println("configOfflineSaveAccount", "Failed to do abi.Pack due to:", err.Error())
return
}
callContractAndSignWrite(cmd, packData, contract, "approve_erc20")
}
func AddToken2LockListCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create_add_lock_list",
Short: "add token to lock list",
Run: AddToken2LockList, //配置账户
}
addAddToken2LockListFlags(cmd)
return cmd
}
func addAddToken2LockListFlags(cmd *cobra.Command) {
cmd.Flags().StringP("symbol", "s", "", "token symbol")
_ = cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("token", "t", "", "token addr")
_ = cmd.MarkFlagRequired("token")
cmd.Flags().StringP("contract", "c", "", "bridgebank contract address")
_ = cmd.MarkFlagRequired("contract")
cmd.Flags().StringP("key", "k", "", "the deployer private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func AddToken2LockList(cmd *cobra.Command, _ []string) {
contract, _ := cmd.Flags().GetString("contract")
symbol, _ := cmd.Flags().GetString("symbol")
token, _ := cmd.Flags().GetString("token")
parameter := fmt.Sprintf("addToken2LockList(%s,%s)", token, symbol)
_, packData, err := evmAbi.Pack(parameter, generated.BridgeBankABI, false)
if nil != err {
fmt.Println("configOfflineSaveAccount", "Failed to do abi.Pack due to:", err.Error())
return
}
callContractAndSignWrite(cmd, packData, contract, "create_add_lock_list")
}
func CreateNewBridgeTokenCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create_bridge_token",
Short: "create new token as ethereum asset on chain33, and it's should be done by operator",
Run: CreateNewBridgeToken, //配置账户
}
addCreateNewBridgeTokenFlags(cmd)
return cmd
}
func addCreateNewBridgeTokenFlags(cmd *cobra.Command) {
cmd.Flags().StringP("symbol", "s", "", "token symbol")
_ = cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("contract", "c", "", "bridgebank contract address")
_ = cmd.MarkFlagRequired("contract")
cmd.Flags().StringP("key", "k", "", "the deployer private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func CreateNewBridgeToken(cmd *cobra.Command, _ []string) {
contract, _ := cmd.Flags().GetString("contract")
symbol, _ := cmd.Flags().GetString("symbol")
parameter := fmt.Sprintf("createNewBridgeToken(%s)", symbol)
_, packData, err := evmAbi.Pack(parameter, generated.BridgeBankABI, false)
if nil != err {
fmt.Println("configOfflineSaveAccount", "Failed to do abi.Pack due to:", err.Error())
return
}
callContractAndSignWrite(cmd, packData, contract, "create_bridge_token")
}
package offline
import (
"fmt"
"time"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/system/crypto/secp256k1"
"github.com/33cn/plugin/plugin/dapp/bridgevmxgo/contracts/generated"
gnosis "github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/gnosis/generated"
"github.com/33cn/plugin/plugin/dapp/dex/utils"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
"github.com/spf13/cobra"
)
/*
./boss4x chain33 offline create -f 1 -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae -n 'deploy crossx to chain33' -r '1N6HstkyLFS8QCeVfdvYxx1xoryXoJtvvZ, [1N6HstkyLFS8QCeVfdvYxx1xoryXoJtvvZ, 155ooMPBTF8QQsGAknkK7ei5D78rwDEFe6, 13zBdQwuyDh7cKN79oT2odkxYuDbgQiXFv, 113ZzVamKfAtGt9dq45fX1mNsEoDiN95HG], [25, 25, 25, 25]' --chainID 33
./boss4x chain33 offline send -f deployCrossX2Chain33.txt
*/
func CreateBridgevmxgoCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "create and sign all the offline txs to deploy bridgevmxgo contracts to chain33 evm (include valset,goAssetBridge,bridgeBank,oracle,bridgeRegistry,mulSign)",
Run: createBridgevmxgo,
}
addCreateCrossBridgeFlags(cmd)
return cmd
}
func addCreateCrossBridgeFlags(cmd *cobra.Command) {
cmd.Flags().StringP("key", "k", "", "the deployer private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
cmd.Flags().StringP("valset", "r", "", "contruct parameter for valset, as: 'addr, [addr, addr, addr, addr], [25, 25, 25, 25]'")
_ = cmd.MarkFlagRequired("valset")
}
func createBridgevmxgo(cmd *cobra.Command, args []string) {
_ = args
var txs []*utils.Chain33OfflineTx
privateKeyStr, _ := cmd.Flags().GetString("key")
var driver secp256k1.Driver
privateKeySli := common.FromHex(privateKeyStr)
privateKey, err := driver.PrivKeyFromBytes(privateKeySli)
if nil != err {
fmt.Println("Failed to do PrivKeyFromBytes")
return
}
fromAddr := address.PubKeyToAddress(privateKey.PubKey().Bytes())
from := common.Address{
Addr: fromAddr,
}
i := 1
fmt.Printf("%d: Going to create Valset\n", i)
i += 1
valsetTx, err := createValsetTxAndSign(cmd, from)
if nil != err {
fmt.Println("Failed to createValsetTxAndSign due to cause:", err.Error())
return
}
txs = append(txs, valsetTx)
fmt.Printf("%d: Going to create EthereumBridge\n", i)
i += 1
goAssetBridgeTx, err := createGoAssetBridgeAndSign(cmd, from, valsetTx.ContractAddr)
if nil != err {
fmt.Println("Failed to createGoAssetBridgeAndSign due to cause:", err.Error())
return
}
txs = append(txs, goAssetBridgeTx)
fmt.Printf("%d: Going to create Oracle\n", i)
i += 1
oracleTx, err := createOracleTxAndSign(cmd, from, valsetTx.ContractAddr, goAssetBridgeTx.ContractAddr)
if nil != err {
fmt.Println("Failed to createOracleTxAndSign due to cause:", err.Error())
return
}
txs = append(txs, oracleTx)
fmt.Printf("%d: Going to create BridgeBank\n", i)
i += 1
bridgeBankTx, err := createBridgeBankTxAndSign(cmd, from, valsetTx.ContractAddr, goAssetBridgeTx.ContractAddr)
if nil != err {
fmt.Println("Failed to createBridgeBankTxAndSign due to cause:", err.Error())
return
}
txs = append(txs, bridgeBankTx)
fmt.Printf("%d: Going to set BridgeBank to EthBridge \n", i)
i += 1
setBridgeBank2GoAssetBridgeTx, err := setBridgeBank2GoAssetBridgeTxAndSign(cmd, goAssetBridgeTx.ContractAddr, bridgeBankTx.ContractAddr)
if nil != err {
fmt.Println("Failed to setBridgeBank2EthBridgeTxAndSign due to cause:", err.Error())
return
}
txs = append(txs, setBridgeBank2GoAssetBridgeTx)
fmt.Printf("%d: Going to set Oracle to EthBridge \n", i)
i += 1
setOracle2EthBridgeTx, err := setOracle2GoAssetBridgeTxAndSign(cmd, goAssetBridgeTx.ContractAddr, oracleTx.ContractAddr)
if nil != err {
fmt.Println("Failed to setOracle2GoAssetBridgeTxAndSign due to cause:", err.Error())
return
}
txs = append(txs, setOracle2EthBridgeTx)
fmt.Printf("%d: Going to create BridgeRegistry \n", i)
i += 1
createBridgeRegistryTx, err := createBridgeRegistryTxAndSign(cmd, from, goAssetBridgeTx.ContractAddr, valsetTx.ContractAddr, bridgeBankTx.ContractAddr, oracleTx.ContractAddr)
if nil != err {
fmt.Println("Failed to createBridgeRegistryTxAndSign due to cause:", err.Error())
return
}
txs = append(txs, createBridgeRegistryTx)
fmt.Printf("%d: Write all the txs to file: %s \n", i, crossXfileName)
utils.WriteToFileInJson(crossXfileName, txs)
}
func createBridgeRegistryTxAndSign(cmd *cobra.Command, from common.Address, ethereumBridge, valset, bridgeBank, oracle string) (*utils.Chain33OfflineTx, error) {
createPara := fmt.Sprintf("%s,%s,%s,%s", ethereumBridge, bridgeBank, oracle, valset)
content, txHash, err := utils.CreateContractAndSign(getTxInfo(cmd), generated.BridgeRegistryBin, generated.BridgeRegistryABI, createPara, "BridgeRegistry")
if nil != err {
return nil, err
}
newContractAddr := common.NewContractAddress(from, txHash).String()
bridgeRegistryTx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy BridgeRegistry",
Interval: time.Second * 5,
}
return bridgeRegistryTx, nil
}
func setOracle2GoAssetBridgeTxAndSign(cmd *cobra.Command, ethbridge, oracle string) (*utils.Chain33OfflineTx, error) {
parameter := fmt.Sprintf("setOracle(%s)", oracle)
_, packData, err := evmAbi.Pack(parameter, generated.GoAssetBridgeABI, false)
if nil != err {
fmt.Println("setOracle2GoAssetBridge", "Failed to do abi.Pack due to:", err.Error())
return nil, err
}
action := &evmtypes.EVMContractAction{Amount: 0, GasLimit: 0, GasPrice: 0, Note: "setOracle2GoAssetBridge", Para: packData, ContractAddr: ethbridge}
content, txHash, err := utils.CallContractAndSign(getTxInfo(cmd), action, ethbridge)
if nil != err {
return nil, err
}
setOracle2EthBridgeTx := &utils.Chain33OfflineTx{
ContractAddr: ethbridge,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "setOracle2GoAssetBridge",
Interval: time.Second * 5,
}
return setOracle2EthBridgeTx, nil
}
func setBridgeBank2GoAssetBridgeTxAndSign(cmd *cobra.Command, ethbridge, bridgebank string) (*utils.Chain33OfflineTx, error) {
parameter := fmt.Sprintf("setBridgeBank(%s)", bridgebank)
_, packData, err := evmAbi.Pack(parameter, generated.GoAssetBridgeABI, false)
if nil != err {
fmt.Println("setBridgeBank2GoAssetBridge", "Failed to do abi.Pack due to:", err.Error())
return nil, err
}
action := &evmtypes.EVMContractAction{Amount: 0, GasLimit: 0, GasPrice: 0, Note: "setBridgeBank2GoAssetBridge", Para: packData, ContractAddr: ethbridge}
content, txHash, err := utils.CallContractAndSign(getTxInfo(cmd), action, ethbridge)
if nil != err {
return nil, err
}
setBridgeBank2EthBridgeTx := &utils.Chain33OfflineTx{
ContractAddr: ethbridge,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "setBridgeBank2GoAssetBridge",
Interval: time.Second * 5,
}
return setBridgeBank2EthBridgeTx, nil
}
func createBridgeBankTxAndSign(cmd *cobra.Command, from common.Address, oracle, ethereumBridge string) (*utils.Chain33OfflineTx, error) {
operator := from.String()
createPara := fmt.Sprintf("%s,%s,%s", operator, oracle, ethereumBridge)
content, txHash, err := utils.CreateContractAndSign(getTxInfo(cmd), generated.BridgeBankBin, generated.BridgeBankABI, createPara, "bridgeBank")
if nil != err {
return nil, err
}
newContractAddr := common.NewContractAddress(from, txHash).String()
bridgeBankTx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy bridgeBank",
Interval: time.Second * 5,
}
return bridgeBankTx, nil
}
func createOracleTxAndSign(cmd *cobra.Command, from common.Address, valset, ethereumBridge string) (*utils.Chain33OfflineTx, error) {
operator := from.String()
createPara := fmt.Sprintf("%s,%s,%s", operator, valset, ethereumBridge)
content, txHash, err := utils.CreateContractAndSign(getTxInfo(cmd), generated.OracleBin, generated.OracleABI, createPara, "oralce")
if nil != err {
return nil, err
}
newContractAddr := common.NewContractAddress(from, txHash).String()
oracleTx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy oracle",
Interval: time.Second * 5,
}
return oracleTx, nil
}
func createValsetTxAndSign(cmd *cobra.Command, from common.Address) (*utils.Chain33OfflineTx, error) {
contructParameter, _ := cmd.Flags().GetString("valset")
createPara := contructParameter
content, txHash, err := utils.CreateContractAndSign(getTxInfo(cmd), generated.ValsetBin, generated.ValsetABI, createPara, "valset")
if nil != err {
return nil, err
}
newContractAddr := common.NewContractAddress(from, txHash).String()
valsetTx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy valset",
Interval: time.Second * 5,
}
return valsetTx, nil
}
func createGoAssetBridgeAndSign(cmd *cobra.Command, from common.Address, valset string) (*utils.Chain33OfflineTx, error) {
operator := from.String()
createPara := fmt.Sprintf("%s,%s", operator, valset)
content, txHash, err := utils.CreateContractAndSign(getTxInfo(cmd), generated.GoAssetBridgeBin, generated.GoAssetBridgeABI, createPara, "goAssetBridge")
if nil != err {
return nil, err
}
newContractAddr := common.NewContractAddress(from, txHash).String()
goAssetBridgeTx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy goAssetBridge",
Interval: time.Second * 5,
}
return goAssetBridgeTx, nil
}
func createMulSignAndSign(cmd *cobra.Command, from common.Address) (*utils.Chain33OfflineTx, error) {
content, txHash, err := utils.CreateContractAndSign(getTxInfo(cmd), gnosis.GnosisSafeBin, gnosis.GnosisSafeABI, "", "mulSign2chain33")
if nil != err {
return nil, err
}
newContractAddr := common.NewContractAddress(from, txHash).String()
mulSign2chain33Tx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy mulSign2chain33",
Interval: time.Second * 5,
}
return mulSign2chain33Tx, nil
}
package offline
import (
"fmt"
"strings"
gnosis "github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/gnosis/generated"
ebTypes "github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer/types"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
"github.com/spf13/cobra"
)
/*
./boss4x chain33 offline multisign_setup -m 1GrhufvPtnBCtfxDrFGcCoihmYMHJafuPn -o 168Sn1DXnLrZHTcAM9stD6t2P49fNuJfJ9,13KTf57aCkVVJYNJBXBBveiA5V811SrLcT,1JQwQWsShTHC4zxHzbUfYQK4kRBriUQdEe,1NHuKqoKe3hyv52PF8XBAyaTmJWAqA2Jbb -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae --chainID 33
./boss4x chain33 offline send -f multisign_setup.txt
*/
func SetupCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "multisign_setup",
Short: "Setup owners to contract",
Run: SetupOwner,
}
SetupOwnerFlags(cmd)
return cmd
}
func SetupOwnerFlags(cmd *cobra.Command) {
cmd.Flags().StringP("owner", "o", "", "owners's address, separated by ','")
_ = cmd.MarkFlagRequired("owner")
cmd.Flags().StringP("key", "k", "", "operator private key")
_ = cmd.MarkFlagRequired("operator")
cmd.Flags().StringP("multisign", "m", "", "multisign contract address")
_ = cmd.MarkFlagRequired("multisign")
}
func SetupOwner(cmd *cobra.Command, _ []string) {
multisign, _ := cmd.Flags().GetString("multisign")
owner, _ := cmd.Flags().GetString("owner")
owners := strings.Split(owner, ",")
BTYAddrChain33 := ebTypes.BTYAddrChain33
parameter := "setup(["
parameter += fmt.Sprintf("%s", owners[0])
for _, owner := range owners[1:] {
parameter += fmt.Sprintf(",%s", owner)
}
parameter += "], "
parameter += fmt.Sprintf("%d, %s, 0102, %s, %s, 0, %s)", len(owners), BTYAddrChain33, BTYAddrChain33, BTYAddrChain33, BTYAddrChain33)
_, packData, err := evmAbi.Pack(parameter, gnosis.GnosisSafeABI, false)
if nil != err {
fmt.Println("multisign_setup", "Failed to do abi.Pack due to:", err.Error())
return
}
callContractAndSignWrite(cmd, packData, multisign, "multisign_setup")
}
package offline
import (
"fmt"
"math/big"
"strings"
"github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/gnosis/generated"
gnosis "github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/gnosis/generated"
chain33Common "github.com/33cn/chain33/common"
"github.com/33cn/chain33/system/crypto/secp256k1"
erc20 "github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/erc20/generated"
chain33Relayer "github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer/relayer/chain33"
ebrelayerTypes "github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer/types"
relayerutils "github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer/utils"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common/math"
btcecsecp256k1 "github.com/btcsuite/btcd/btcec"
ethSecp256k1 "github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/spf13/cobra"
)
/*
./boss4x chain33 offline create_multisign_transfer -a 10 -r 168Sn1DXnLrZHTcAM9stD6t2P49fNuJfJ9 -m 1NFDfEwne4kjuxAZrtYEh4kfSrnGSE7ap
./boss4x chain33 offline multisign_transfer -k 0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262a -s 0xcd284cd17456b73619fa609bb9e3105e8eff5d059c5e0b6eb1effbebd4d64144,0xe892212221b3b58211b90194365f4662764b6d5474ef2961ef77c909e31eeed3,0x9d19a2e9a440187010634f4f08ce36e2bc7b521581436a99f05568be94dc66ea,0x45d4ce009e25e6d5e00d8d3a50565944b2e3604aa473680a656b242d9acbff35 --chainID 33
./boss4x chain33 offline send -f multisign_transfer.txt
*/
type transferTxData struct {
Receiver string
Token string
MultisignAddr string
Data string
Amount float64
name string
}
func CreateMultisignTransferCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create_multisign_transfer",
Short: "create multisign transfer tx",
Run: CreateMultisignTransfer,
}
addCreateMultisignTransferFlags(cmd)
return cmd
}
func addCreateMultisignTransferFlags(cmd *cobra.Command) {
cmd.Flags().StringP("receiver", "r", "", "receive address")
_ = cmd.MarkFlagRequired("receiver")
cmd.Flags().Float64P("amount", "a", 0, "amount to transfer")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("token", "t", "", "erc20 address,not need to set for BTY(optional)")
//
cmd.Flags().StringP("address", "m", "", "multisign address")
_ = cmd.MarkFlagRequired("address")
}
func CreateMultisignTransfer(cmd *cobra.Command, _ []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
receiver, _ := cmd.Flags().GetString("receiver")
token, _ := cmd.Flags().GetString("token")
amount, _ := cmd.Flags().GetFloat64("amount")
multisign, _ := cmd.Flags().GetString("address")
//对于平台币转账,这个data只是个占位符,没有作用
dataStr := "0x"
safeTxGas := int64(10 * 10000)
baseGas := 0
gasPrice := 0
valueStr := relayerutils.ToWei(amount, 8).String()
//如果是bty转账,则直接将to地址设置为receiver,而如果是ERC20转账,则需要将其设置为token地址
to := receiver
//如果是erc20转账,则需要构建data数据
if "" != token {
parameter := fmt.Sprintf("transfer(%s, %s)", receiver, relayerutils.ToWei(amount, 8).String())
_, data, err := evmAbi.Pack(parameter, erc20.ERC20ABI, false)
if err != nil {
fmt.Println("Failed to do abi.Pack due to:", err.Error())
return
}
//对于其他erc20资产,直接将其设置为0
valueStr = "0"
to = token
dataStr = chain33Common.ToHex(data)
}
//获取nonce
nonce := getMulSignNonce(multisign, rpcLaddr)
parameter2getHash := fmt.Sprintf("getTransactionHash(%s, %s, %s, 0, %d, %d, %d, %s, %s, %d)", to, valueStr, dataStr,
safeTxGas, baseGas, gasPrice, ebrelayerTypes.NilAddrChain33, ebrelayerTypes.NilAddrChain33, nonce)
result := chain33Relayer.Query(multisign, parameter2getHash, multisign, rpcLaddr, generated.GnosisSafeABI)
if nil == result {
fmt.Println("Failed to getTransactionHash :", ebrelayerTypes.ErrGetTransactionHash)
return
}
contentHashArray := result.([32]byte)
contentHash := contentHashArray[:]
var txinfo transferTxData
txinfo.Receiver = receiver
txinfo.MultisignAddr = multisign
txinfo.Amount = amount
txinfo.Data = chain33Common.ToHex(contentHash)
txinfo.Token = token
txinfo.name = "create_multisign_transfer"
writeToFile(txinfo.name+".txt", txinfo)
}
func MultisignTransferCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "multisign_transfer",
Short: "create multisign transfer tx and sign",
Run: MultisignTransfer,
}
addMultisignTransferFlags(cmd)
return cmd
}
func addMultisignTransferFlags(cmd *cobra.Command) {
cmd.Flags().StringP("file", "t", "create_multisign_transfer.txt", "tx file, default: create_multisign_transfer.txt")
cmd.Flags().StringP("keys", "s", "", "owners' private key, separated by ','")
_ = cmd.MarkFlagRequired("keys")
cmd.Flags().StringP("key", "k", "", "the deployer private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func MultisignTransfer(cmd *cobra.Command, _ []string) {
keysStr, _ := cmd.Flags().GetString("keys")
keys := strings.Split(keysStr, ",")
txFilePath, _ := cmd.Flags().GetString("file")
var txinfo transferTxData
err := paraseFile(txFilePath, &txinfo)
if err != nil {
fmt.Println("paraseFile Err:", err)
return
}
//对于平台币转账,这个data只是个占位符,没有作用
dataStr := "0x"
contentHash, err := chain33Common.FromHex(txinfo.Data)
safeTxGas := int64(10 * 10000)
baseGas := 0
gasPrice := 0
valueStr := relayerutils.ToWei(txinfo.Amount, 8).String()
//如果是bty转账,则直接将to地址设置为receiver,而如果是ERC20转账,则需要将其设置为token地址
to := txinfo.Receiver
//如果是erc20转账,则需要构建data数据
if "" != txinfo.Token {
parameter := fmt.Sprintf("transfer(%s, %s)", txinfo.Receiver, relayerutils.ToWei(txinfo.Amount, 8).String())
_, data, err := evmAbi.Pack(parameter, erc20.ERC20ABI, false)
if err != nil {
fmt.Println("evmAbi.Pack(parameter, erc20.ERC20ABI, false)", "Failed", err.Error())
return
}
//对于其他erc20资产,直接将其设置为0
valueStr = "0"
to = txinfo.Token
dataStr = chain33Common.ToHex(data)
}
var sigs []byte
for _, privateKey := range keys {
var driver secp256k1.Driver
privateKeySli, err := chain33Common.FromHex(privateKey)
if nil != err {
fmt.Println("evmAbi.Pack(parameter, erc20.ERC20ABI, false)", "Failed", err.Error())
return
}
ownerPrivateKey, err := driver.PrivKeyFromBytes(privateKeySli)
if nil != err {
fmt.Println("evmAbi.Pack(parameter, erc20.ERC20ABI, false)", "Failed", err.Error())
return
}
temp, _ := btcecsecp256k1.PrivKeyFromBytes(btcecsecp256k1.S256(), ownerPrivateKey.Bytes())
privateKey4chain33Ecdsa := temp.ToECDSA()
sig, err := ethSecp256k1.Sign(contentHash, math.PaddedBigBytes(privateKey4chain33Ecdsa.D, 32))
if nil != err {
fmt.Println("evmAbi.Pack(parameter, erc20.ERC20ABI, false)", "Failed", err.Error())
return
}
sig[64] += 27
sigs = append(sigs, sig...)
}
//构造execTransaction参数
parameter2Exec := fmt.Sprintf("execTransaction(%s, %s, %s, 0, %d, %d, %d, %s, %s, %s)", to, valueStr, dataStr,
safeTxGas, baseGas, gasPrice, ebrelayerTypes.NilAddrChain33, ebrelayerTypes.NilAddrChain33, chain33Common.ToHex(sigs))
_, packData, err := evmAbi.Pack(parameter2Exec, gnosis.GnosisSafeABI, false)
if nil != err {
fmt.Println("execTransaction evmAbi.Pack", "Failed", err.Error())
return
}
callContractAndSignWrite(cmd, packData, txinfo.MultisignAddr, "multisign_transfer")
}
func getMulSignNonce(mulsign, rpcLaddr string) int64 {
parameter := fmt.Sprintf("nonce()")
result := chain33Relayer.Query(mulsign, parameter, mulsign, rpcLaddr, gnosis.GnosisSafeABI)
if nil == result {
return 0
}
nonce := result.(*big.Int)
return nonce.Int64()
}
package offline
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"github.com/33cn/plugin/plugin/dapp/dex/utils"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
"github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra"
)
var crossXfileName = "deployBridgevmxgo2Chain33.txt"
func Boss4xOfflineCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "offline",
Short: "create and sign offline tx to deploy and set cross contracts to chain33",
}
cmd.AddCommand(
CreateBridgevmxgoCmd(),
SendSignTxs2Chain33Cmd(),
CreateERC20Cmd(),
ApproveErc20Cmd(),
AddToken2LockListCmd(),
CreateNewBridgeTokenCmd(),
SetupCmd(),
ConfigOfflineSaveAccountCmd(),
ConfigLockedTokenOfflineSaveCmd(),
CreateMultisignTransferCmd(),
MultisignTransferCmd(),
)
return cmd
}
func SendSignTxs2Chain33Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "send",
Short: "send all the txs to chain33 in serial",
Run: sendSignTxs2Chain33,
}
addSendSignTxs2Chain33Flags(cmd)
return cmd
}
func addSendSignTxs2Chain33Flags(cmd *cobra.Command) {
cmd.Flags().StringP("file", "f", "", "signed tx file")
_ = cmd.MarkFlagRequired("file")
}
func sendSignTxs2Chain33(cmd *cobra.Command, _ []string) {
filePath, _ := cmd.Flags().GetString("file")
url, _ := cmd.Flags().GetString("rpc_laddr")
utils.SendSignTxs2Chain33(filePath, url)
}
func getTxInfo(cmd *cobra.Command) *utils.TxCreateInfo {
privateKey, _ := cmd.Flags().GetString("key")
expire, _ := cmd.Flags().GetString("expire")
note, _ := cmd.Flags().GetString("note")
fee, _ := cmd.Flags().GetFloat64("fee")
paraName, _ := cmd.Flags().GetString("paraName")
chainID, _ := cmd.Flags().GetInt32("chainID")
feeInt64 := int64(fee*1e4) * 1e4
info := &utils.TxCreateInfo{
PrivateKey: privateKey,
Expire: expire,
Note: note,
Fee: feeInt64,
ParaName: paraName,
ChainID: chainID,
}
return info
}
func writeToFile(fileName string, content interface{}) {
jbytes, err := json.MarshalIndent(content, "", "\t")
if err != nil {
panic(err)
}
err = ioutil.WriteFile(fileName, jbytes, 0666)
if err != nil {
fmt.Println("Failed to write to file:", fileName)
}
fmt.Println("tx is written to file: ", fileName)
}
func paraseFile(file string, result interface{}) error {
_, err := os.Stat(file)
if err != nil {
fmt.Println(err.Error())
return err
}
f, err := os.Open(file)
if err != nil {
panic(err)
}
b, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
return json.Unmarshal(b, result)
}
func callContractAndSignWrite(cmd *cobra.Command, para []byte, contractAddr, name string) {
action := &evmtypes.EVMContractAction{Amount: 0, GasLimit: 0, GasPrice: 0, Note: name, Para: para, ContractAddr: contractAddr}
content, txHash, err := utils.CallContractAndSign(getTxInfo(cmd), action, contractAddr)
if nil != err {
fmt.Println("CallContractAndSign", "Failed", err.Error())
return
}
Tx := &utils.Chain33OfflineTx{
ContractAddr: contractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: name,
}
_, err = json.MarshalIndent(Tx, "", " ")
if err != nil {
fmt.Println("MarshalIndent error", err.Error())
return
}
var txs []*utils.Chain33OfflineTx
txs = append(txs, Tx)
fileName := fmt.Sprintf(Tx.OperationName + ".txt")
fmt.Printf("Write all the txs to file: %s \n", fileName)
utils.WriteToFileInJson(fileName, txs)
}
package main
import (
"fmt"
"net/http"
"os"
"strings"
"github.com/33cn/plugin/plugin/dapp/bridgevmxgo/boss4x/buildFlags"
"github.com/33cn/plugin/plugin/dapp/bridgevmxgo/boss4x/chain33"
"github.com/spf13/cobra"
)
func main() {
if buildFlags.RPCAddr4Chain33 == "" {
buildFlags.RPCAddr4Chain33 = "http://localhost:8801"
}
buildFlags.RPCAddr4Chain33 = testTLS(buildFlags.RPCAddr4Chain33)
rootCmd := RootCmd()
rootCmd.PersistentFlags().String("rpc_laddr", buildFlags.RPCAddr4Chain33, "http url")
rootCmd.PersistentFlags().String("paraName", "", "para chain name,Eg:user.p.fzm.")
rootCmd.PersistentFlags().String("expire", "120m", "transaction expire time (optional)")
rootCmd.PersistentFlags().Int32("chainID", 0, "chain id, default to 0")
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
// RootCmd Cmd x2ethereum client command
func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "boss for bridgevmxgo",
Short: "manage create offline tx or deploy contracts(bridgevmxgo) for test",
}
cmd.AddCommand(
chain33.Chain33Cmd(),
)
return cmd
}
func testTLS(RPCAddr string) string {
rpcaddr := RPCAddr
if !strings.HasPrefix(rpcaddr, "http://") {
return RPCAddr
}
// if http://
if rpcaddr[len(rpcaddr)-1] != '/' {
rpcaddr += "/"
}
rpcaddr += "test"
/* #nosec */
resp, err := http.Get(rpcaddr)
if err != nil {
return "https://" + RPCAddr[7:]
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
return RPCAddr
}
return "https://" + RPCAddr[7:]
}
all:
chmod +x ./build.sh
./build.sh $(OUT) $(FLAG)
#!/usr/bin/env bash
# 官方ci集成脚本
strpwd=$(pwd)
strcmd=${strpwd##*dapp/}
strapp=${strcmd%/cmd*}
SRC_EBCLI=github.com/33cn/plugin/plugin/dapp/cross2eth/ebcli
SRC_EBRELAYER=github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer
SRC_BOSS4XCLI=github.com/33cn/plugin/plugin/dapp/cross2eth/boss4x
SRC_EVMXGOBOSS4XCLI=github.com/33cn/plugin/plugin/dapp/bridgevmxgo/boss4x
OUT_DIR="${1}/$strapp"
FLAG=$2
# shellcheck disable=SC2086,1072
go build -i ${FLAG} -v -o "${OUT_DIR}/ebrelayer" "${SRC_EBRELAYER}"
# shellcheck disable=SC2086,1072
go build -i ${FLAG} -v -o "${OUT_DIR}/ebcli_A" "${SRC_EBCLI}"
# shellcheck disable=SC2086,1072
go build -i ${FLAG} -v -o "${OUT_DIR}/ebcli_B" -ldflags "-X ${SRC_EBCLI}/buildflags.RPCAddr=http://localhost:9902" "${SRC_EBCLI}"
# shellcheck disable=SC2086,1072
go build -i ${FLAG} -v -o "${OUT_DIR}/ebcli_C" -ldflags "-X ${SRC_EBCLI}/buildflags.RPCAddr=http://localhost:9903" "${SRC_EBCLI}"
# shellcheck disable=SC2086,1072
go build -i ${FLAG} -v -o "${OUT_DIR}/ebcli_D" -ldflags "-X ${SRC_EBCLI}/buildflags.RPCAddr=http://localhost:9904" "${SRC_EBCLI}"
# shellcheck disable=SC2086,1072
go build -i ${FLAG} -v -o "${OUT_DIR}/boss4x" "${SRC_BOSS4XCLI}"
# shellcheck disable=SC2086,1072
go build -i ${FLAG} -v -o "${OUT_DIR}/evmxgoboss4x" "${SRC_EVMXGOBOSS4XCLI}"
cp ../../../../chain33.para.toml "${OUT_DIR}"
cp ../../cross2eth/ebrelayer/relayer.toml "${OUT_DIR}/relayer.toml"
cp ./build/* "${OUT_DIR}"
cp ./build/abi/* "${OUT_DIR}"
cp ./build/public/* "${OUT_DIR}"
OUT_TESTDIR="${1}/dapptest/$strapp"
mkdir -p "${OUT_TESTDIR}"
cp ./test/* "${OUT_TESTDIR}"
FROM ubuntu:16.04
WORKDIR /root
COPY chain33 chain33
COPY chain33-cli chain33-cli
COPY chain33.toml chain33*.toml ./
COPY entrypoint.sh entrypoint.sh
CMD ["/root/chain33", "-f", "/root/chain33.toml"]
FROM ubuntu:16.04
WORKDIR /root
COPY ebrelayer ebrelayer
COPY ebcli_A ebcli_A
COPY boss4x boss4x
COPY evmxgoboss4x evmxgoboss4x
COPY sleep.sh sleep.sh
CMD ["/root/sleep.sh"]
[{"inputs":[{"internalType":"address","name":"_ethereumBridge","type":"address"},{"internalType":"address","name":"_bridgeBank","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_valset","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_ethereumBridge","type":"address"},{"indexed":false,"internalType":"address","name":"_bridgeBank","type":"address"},{"indexed":false,"internalType":"address","name":"_oracle","type":"address"},{"indexed":false,"internalType":"address","name":"_valset","type":"address"}],"name":"LogContractsRegistered","type":"event"},{"constant":true,"inputs":[],"name":"bridgeBank","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"deployHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ethereumBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"valset","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]
\ No newline at end of file
[{"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
[{"inputs":[{"internalType":"address","name":"_operatorAddress","type":"address"},{"internalType":"address","name":"_oracleAddress","type":"address"},{"internalType":"address","name":"_ethereumBridgeAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_beneficiary","type":"address"}],"name":"LogBridgeTokenMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_ownerFrom","type":"address"},{"indexed":false,"internalType":"bytes","name":"_ethereumReceiver","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"LogEthereumTokenBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"bytes","name":"_to","type":"bytes"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"LogLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"}],"name":"LogNewBridgeToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"LogUnlock","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"addToken2LockList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"bridgeTokenCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"bridgeTokenCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bridgeTokenWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_ethereumReceiver","type":"bytes"},{"internalType":"address","name":"_ethereumTokenAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnBridgeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint8","name":"_percents","type":"uint8"}],"name":"configLockedTokenOfflineSave","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"addresspayable","name":"_offlineSave","type":"address"}],"name":"configOfflineSaveAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"createNewBridgeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ethereumBridge","outputs":[{"internalType":"contractEthereumBridge","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getEthereumDepositStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getLockedTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getToken2address","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getofflineSaveCfg","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"hasBridgeTokenCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"highThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_recipient","type":"bytes"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"lock","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"lockNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockedFunds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lowThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_ethereumSender","type":"bytes"},{"internalType":"addresspayable","name":"_intendedRecipient","type":"address"},{"internalType":"address","name":"_bridgeTokenAddress","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintBridgeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"offlineSave","outputs":[{"internalType":"addresspayable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"offlineSaveCfgs","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint8","name":"_percents","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"internalType":"contractOracle","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"token2address","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"tokenAllow2Lock","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"addresspayable","name":"_recipient","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"viewEthereumDeposit","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"addresspayable","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
\ No newline at end of file
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
[{"inputs":[{"internalType":"address","name":"_operatorAddress","type":"address"},{"internalType":"address","name":"_oracleAddress","type":"address"},{"internalType":"address","name":"_chain33BridgeAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_beneficiary","type":"address"}],"name":"LogBridgeTokenMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_ownerFrom","type":"address"},{"indexed":false,"internalType":"bytes","name":"_chain33Receiver","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"LogChain33TokenBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"bytes","name":"_to","type":"bytes"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"LogLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"}],"name":"LogNewBridgeToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"LogUnlock","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"addToken2LockList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"bridgeTokenCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"bridgeTokenCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bridgeTokenWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_chain33Receiver","type":"bytes"},{"internalType":"address","name":"_chain33TokenAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnBridgeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"chain33Bridge","outputs":[{"internalType":"contractChain33Bridge","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint8","name":"_percents","type":"uint8"}],"name":"configLockedTokenOfflineSave","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"addresspayable","name":"_offlineSave","type":"address"}],"name":"configOfflineSaveAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"createNewBridgeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getChain33DepositStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getLockedTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getToken2address","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getToken2addressV2","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getofflineSaveCfg","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"hasBridgeTokenCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"highThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_recipient","type":"bytes"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"lock","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"lockNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockedFunds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lowThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_chain33Sender","type":"bytes"},{"internalType":"addresspayable","name":"_intendedRecipient","type":"address"},{"internalType":"address","name":"_bridgeTokenAddress","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintBridgeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"offlineSave","outputs":[{"internalType":"addresspayable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"offlineSaveCfgs","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint8","name":"_percents","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"internalType":"contractOracle","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"token2address","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"tokenAllow2Lock","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"addresspayable","name":"_recipient","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"viewChain33Deposit","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"addresspayable","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
\ No newline at end of file
[{"inputs":[{"internalType":"address","name":"_goAssetBridge","type":"address"},{"internalType":"address","name":"_bridgeBank","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_valset","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_goAssetBridge","type":"address"},{"indexed":false,"internalType":"address","name":"_bridgeBank","type":"address"},{"indexed":false,"internalType":"address","name":"_oracle","type":"address"},{"indexed":false,"internalType":"address","name":"_valset","type":"address"}],"name":"LogContractsRegistered","type":"event"},{"constant":true,"inputs":[],"name":"bridgeBank","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"deployHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"goAssetBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"valset","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]
\ No newline at end of file
[{"inputs":[{"internalType":"address","name":"_operatorAddress","type":"address"},{"internalType":"address","name":"_oracleAddress","type":"address"},{"internalType":"address","name":"_goAssetBridgeAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_beneficiary","type":"address"}],"name":"LogBridgeTokenMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_ownerFrom","type":"address"},{"indexed":false,"internalType":"address","name":"_goAssetReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"LogGoAssetTokenBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"LogLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"}],"name":"LogNewBridgeToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"LogUnlock","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"addToken2LockList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"bridgeTokenCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"bridgeTokenCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bridgeTokenWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_goAssetReceiver","type":"address"},{"internalType":"address","name":"_goAssetTokenAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnBridgeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint8","name":"_percents","type":"uint8"}],"name":"configLockedTokenOfflineSave","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"addresspayable","name":"_offlineSave","type":"address"}],"name":"configOfflineSaveAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"createNewBridgeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getGoAssetDepositStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getLockedTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getToken2address","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getofflineSaveCfg","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"goAssetBridge","outputs":[{"internalType":"contractGoAssetBridge","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"hasBridgeTokenCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"highThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"lock","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"lockNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockedFunds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lowThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_goAssetSender","type":"address"},{"internalType":"addresspayable","name":"_intendedRecipient","type":"address"},{"internalType":"address","name":"_bridgeTokenAddress","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintBridgeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"offlineSave","outputs":[{"internalType":"addresspayable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"offlineSaveCfgs","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint8","name":"_percents","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"internalType":"contractOracle","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"token2address","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"tokenAllow2Lock","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"addresspayable","name":"_recipient","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"viewGoAssetDeposit","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"addresspayable","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
\ No newline at end of file
[{"inputs":[{"internalType":"address","name":"_operatorAddress","type":"address"},{"internalType":"address","name":"_oracleAddress","type":"address"},{"internalType":"address","name":"_goAssetBridgeAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_beneficiary","type":"address"}],"name":"LogBridgeTokenMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_ownerFrom","type":"address"},{"indexed":false,"internalType":"address","name":"_goAssetReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"LogGoAssetTokenBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"LogLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"}],"name":"LogNewBridgeToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"LogUnlock","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"addToken2LockList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"bridgeTokenCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"bridgeTokenCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bridgeTokenWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_goAssetReceiver","type":"address"},{"internalType":"address","name":"_goAssetTokenAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnBridgeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint8","name":"_percents","type":"uint8"}],"name":"configLockedTokenOfflineSave","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"addresspayable","name":"_offlineSave","type":"address"}],"name":"configOfflineSaveAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"createNewBridgeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getGoAssetDepositStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getLockedTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"getToken2address","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getofflineSaveCfg","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"goAssetBridge","outputs":[{"internalType":"contractGoAssetBridge","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"hasBridgeTokenCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"highThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"lock","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"lockNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockedFunds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lowThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_goAssetSender","type":"address"},{"internalType":"addresspayable","name":"_intendedRecipient","type":"address"},{"internalType":"address","name":"_bridgeTokenAddress","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintBridgeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"offlineSave","outputs":[{"internalType":"addresspayable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"offlineSaveCfgs","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint8","name":"_percents","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"internalType":"contractOracle","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"token2address","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"tokenAllow2Lock","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"addresspayable","name":"_recipient","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"viewGoAssetDeposit","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"addresspayable","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
\ No newline at end of file
version: '3'
services:
ganachetest:
entrypoint: ["node", "/app/ganache-core.docker.cli.js", "-a", "20", "-b", "2", "--debug", "-m", "coast bar giraffe art venue decide symbol law visual crater vital fold", "-e", "1000"]
image: trufflesuite/ganache-cli:latest
ports:
- "8545:8545"
ebrelayera:
build:
context: .
dockerfile: Dockerfile-bridgevmxgo
ports:
- "9901:9901"
ebrelayerb:
build:
context: .
dockerfile: Dockerfile-bridgevmxgo
ebrelayerc:
build:
context: .
dockerfile: Dockerfile-bridgevmxgo
ebrelayerd:
build:
context: .
dockerfile: Dockerfile-bridgevmxgo
chain33:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para33.toml"
expose:
- "8802"
ports:
- "8801:8801"
- "8901:8901"
chain32:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para32.toml"
chain31:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para31.toml"
chain30:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para30.toml"
expose:
- "8802"
chain29:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para29.toml"
nginx:
image: nginx:latest
depends_on:
- chain33
- chain30
- chain29
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
expose:
- "8803"
\ No newline at end of file
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
set -x
set +e
# 主要在平行链上测试
source "./offlinePublic.sh"
maturityDegree=10
chain33BridgeBank=""
ethBridgeBank=""
chain33BtyERC20TokenAddr="1111111111111111111114oLvT2"
ethereumBtyBridgeTokenAddr=""
chain33EthBridgeTokenAddr=""
ethereumBycERC20TokenAddr=""
chain33BycBridgeTokenAddr=""
chain33YccERC20TokenAddr=""
ethereumYccBridgeTokenAddr=""
chain33ZbcERC20TokenAddr=""
ethereumZbcBridgeTokenAddr=""
BridgeRegistryOnChain33=""
BridgeRegistryOnEth=""
multisignChain33Addr=""
multisignEthAddr=""
chain33ID=0
EvmxgoBoss4xCLI="./evmxgoboss4x"
# shellcheck disable=SC2034
{
# ETH 部署合约者的私钥 用于部署合约时签名使用
ethDeployAddr="0x8AFDADFC88a1087c9A1D6c0F5Dd04634b87F303a"
ethDeployKey="0x8656d2bc732a8a816a461ba5e2d8aac7c7f85c26a813df30d5327210465eb230"
# chain33 部署合约者的私钥 用于部署合约时签名使用
chain33DeployAddr="1JxhYLYsrscjTaQfaMoVUrnSdrejP7XRQD"
chain33DeployKey="0x9ef82623a5e9aac58d3a6b06392af66ec77289522b28896aed66abaaede66903"
# validatorsAddr=["0x92C8b16aFD6d423652559C6E266cBE1c29Bfd84f", "0x0df9a824699bc5878232c9e612fe1a5346a5a368", "0xcb074cb21cdddf3ce9c3c0a7ac4497d633c9d9f1", "0xd9dab021e74ecf475788ed7b61356056b2095830"]# shellcheck disable=SC2034
# eth 验证者私钥
ethValidatorAddra="0x92C8b16aFD6d423652559C6E266cBE1c29Bfd84f"
ethValidatorAddrb="0x0df9a824699bc5878232c9e612fe1a5346a5a368"
ethValidatorAddrc="0xcb074cb21cdddf3ce9c3c0a7ac4497d633c9d9f1"
ethValidatorAddrd="0xd9dab021e74ecf475788ed7b61356056b2095830"
ethValidatorAddrKeya="3fa21584ae2e4fd74db9b58e2386f5481607dfa4d7ba0617aaa7858e5025dc1e"
ethValidatorAddrKeyb="a5f3063552f4483cfc20ac4f40f45b798791379862219de9e915c64722c1d400"
ethValidatorAddrKeyc="bbf5e65539e9af0eb0cfac30bad475111054b09c11d668fc0731d54ea777471e"
ethValidatorAddrKeyd="c9fa31d7984edf81b8ef3b40c761f1847f6fcd5711ab2462da97dc458f1f896b"
# 新增地址 chain33 需要导入地址 转入 10 bty当收费费
chain33Validatora="1N6HstkyLFS8QCeVfdvYxx1xoryXoJtvvZ"
chain33Validatorb="155ooMPBTF8QQsGAknkK7ei5D78rwDEFe6"
chain33Validatorc="13zBdQwuyDh7cKN79oT2odkxYuDbgQiXFv"
chain33Validatord="113ZzVamKfAtGt9dq45fX1mNsEoDiN95HG"
chain33ValidatorKeya="0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae"
chain33ValidatorKeyb="0x9d539bc5fd084eb7fe86ad631dba9aa086dba38418725c38d9751459f567da66"
chain33ValidatorKeyc="0x0a6671f101e30a2cc2d79d77436b62cdf2664ed33eb631a9c9e3f3dd348a23be"
chain33ValidatorKeyd="0x3818b257b05ee75b6e43ee0e3cfc2d8502342cf67caed533e3756966690b62a5"
ethTestAddr1=0xbc333839E37bc7fAAD0137aBaE2275030555101f
ethTestAddrKey1=0x0c61f5a879d70807686e43eccc1f52987a15230ae0472902834af4d1933674f2
ethTestAddr2=0x495953A743ef169EC5D4aC7b5F786BF2Bd56aFd5
ethTestAddrKey2=0x2809477ede1261da21270096776ba7dc68b89c9df5f029965eaa5fe7f0b80697
ethReceiverAddr1="0xa4ea64a583f6e51c3799335b28a8f0529570a635"
#ethReceiverAddrKey1="355b876d7cbcb930d5dfab767f66336ce327e082cbaa1877210c1bae89b1df71"
chain33TestAddr1="1Cj1rqUenPmkeD6A8MGEzkBKQFN2H9yL3x"
chain33TestAddrKey1="0x7269a7a87d476310da37a9ca1ddc9333c9d7a0dfe1f2998b84758843a895433b"
chain33TestAddr2="1BCGLhdcdthNutQowV2YShuuN9fJRRGLxu"
chain33TestAddrKey2="0xb74acfd4eebbbd07bcae212baa7f094235ab8dc04f2f1d828681477b98b24008"
chain33ReceiverAddr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
chain33ReceiverAddrKey="4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01"
}
function start_docker_ebrelayerA() {
# shellcheck disable=SC2154
docker cp "./relayer.toml" "${dockerNamePrefix}_ebrelayera_1":/root/relayer.toml
start_docker_ebrelayer "${dockerNamePrefix}_ebrelayera_1" "/root/ebrelayer" "./ebrelayera.log"
sleep 5
}
# start ebrelayer B C D
function updata_toml_start_bcd() {
for name in b c d; do
local file="./relayer$name.toml"
cp './relayer.toml' "${file}"
# 删除配置文件中不需要的字段
for deleteName in "deploy4chain33" "deployerPrivateKey" "operatorAddr" "validatorsAddr" "initPowers" "deploy" "deployerPrivateKey" "operatorAddr" "validatorsAddr" "initPowers"; do
delete_line "${file}" "${deleteName}"
done
pushNameChange "${file}"
pushHost=$(get_docker_addr "${dockerNamePrefix}_ebrelayer${name}_1")
line=$(delete_line_show "${file}" "pushHost")
sed -i ''"${line}"' a pushHost="http://'"${pushHost}"':20000"' "${file}"
line=$(delete_line_show "${file}" "pushBind")
sed -i ''"${line}"' a pushBind="'"${pushHost}"':20000"' "${file}"
docker cp "${file}" "${dockerNamePrefix}_ebrelayer${name}_1":/root/relayer.toml
start_docker_ebrelayer "${dockerNamePrefix}_ebrelayer${name}_1" "/root/ebrelayer" "./ebrelayer${name}.log"
CLI="docker exec ${dockerNamePrefix}_ebrelayer${name}_1 /root/ebcli_A"
result=$(${CLI} set_pwd -p 123456hzj)
cli_ret "${result}" "set_pwd"
result=$(${CLI} unlock -p 123456hzj)
cli_ret "${result}" "unlock"
eval chain33ValidatorKey=\$chain33ValidatorKey${name}
# shellcheck disable=SC2154
result=$(${CLI} chain33 import_privatekey -k "${chain33ValidatorKey}")
cli_ret "${result}" "chain33 import_privatekey"
eval ethValidatorAddrKey=\$ethValidatorAddrKey${name}
# shellcheck disable=SC2154
result=$(${CLI} ethereum import_privatekey -k "${ethValidatorAddrKey}")
cli_ret "${result}" "ethereum import_privatekey"
done
}
function restart_ebrelayerA() {
# 重启
kill_docker_ebrelayer "${dockerNamePrefix}_ebrelayera_1"
sleep 1
start_docker_ebrelayerA
result=$(${CLIA} unlock -p 123456hzj)
cli_ret "${result}" "unlock"
}
# chain33 lock BTY, eth burn BTY
function TestChain33ToEthAssets() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== chain33 lock BTY, eth burn BTY ===========${NOC}"
result=$(${CLIA} ethereum balance -o "${ethTestAddr1}" -t "${ethereumBtyBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "0"
# 原来的地址金额
result=$(${Chain33Cli} asset balance -a "${chain33TestAddr1}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "500.0000"
# chain33 lock bty
hash=$(${Chain33Cli} send evm call -f 1 -a 5 -k "${chain33TestAddr1}" -e "${chain33BridgeBank}" -p "lock(${ethTestAddr1}, ${chain33BtyERC20TokenAddr}, 500000000)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
# 原来的地址金额 减少了 5
result=$(${Chain33Cli} asset balance -a "${chain33TestAddr1}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "495.0000"
# chain33BridgeBank 是否增加了 5
result=$(${Chain33Cli} asset balance -a "${chain33BridgeBank}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "5.0000"
sleep 4
# eth 这端 金额是否增加了 5
result=$(${CLIA} ethereum balance -o "${ethTestAddr1}" -t "${ethereumBtyBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "5"
# eth burn
result=$(${CLIA} ethereum burn -m 3 -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}" -t "${ethereumBtyBridgeTokenAddr}") #--node_addr https://ropsten.infura.io/v3/9e83f296716142ffbaeaafc05790f26c)
cli_ret "${result}" "burn"
sleep 4
# eth 这端 金额是否减少了 3
result=$(${CLIA} ethereum balance -o "${ethTestAddr1}" -t "${ethereumBtyBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "2"
sleep ${maturityDegree}
# 接收的地址金额 变成了 3
result=$(${Chain33Cli} asset balance -a "${chain33ReceiverAddr}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "3.0000"
# chain33BridgeBank 是否减少了 3
result=$(${Chain33Cli} asset balance -a "${chain33BridgeBank}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "2.0000"
# eth burn 2
result=$(${CLIA} ethereum burn -m 2 -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}" -t "${ethereumBtyBridgeTokenAddr}") #--node_addr https://ropsten.infura.io/v3/9e83f296716142ffbaeaafc05790f26c)
cli_ret "${result}" "burn"
sleep 4
# eth 这端 金额是否减少了
result=$(${CLIA} ethereum balance -o "${ethTestAddr1}" -t "${ethereumBtyBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "0"
sleep ${maturityDegree}
# 接收的地址金额 变成了 5
result=$(${Chain33Cli} asset balance -a "${chain33ReceiverAddr}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "5.0000"
# chain33BridgeBank 是否减少了 3
result=$(${Chain33Cli} asset balance -a "${chain33BridgeBank}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "0.0000"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# chain33 lock ZBC, eth burn ZBC
function TestChain33ToEthZBCAssets() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== chain33 lock ZBC, eth burn ZBC ===========${NOC}"
result=$(${CLIA} ethereum balance -o "${ethTestAddr1}" -t "${ethereumZbcBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "0"
# 原来的地址金额
result=$(${Chain33Cli} evm query -a "${chain33ZbcERC20TokenAddr}" -c "${chain33BridgeBank}" -b "balanceOf(${chain33BridgeBank})")
is_equal "${result}" "0"
# chain33 lock ZBC
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33TestAddr1}" -e "${chain33BridgeBank}" -p "lock(${ethTestAddr1}, ${chain33ZbcERC20TokenAddr}, 900000000)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
# chain33BridgeBank 是否增加了 9
result=$(${Chain33Cli} evm query -a "${chain33ZbcERC20TokenAddr}" -c "${chain33BridgeBank}" -b "balanceOf(${chain33BridgeBank})")
is_equal "${result}" "900000000"
sleep 4
# eth 这端 金额是否增加了 9
result=$(${CLIA} ethereum balance -o "${ethTestAddr1}" -t "${ethereumZbcBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "9"
# eth burn
result=$(${CLIA} ethereum burn -m 8 -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}" -t "${ethereumZbcBridgeTokenAddr}") #--node_addr https://ropsten.infura.io/v3/9e83f296716142ffbaeaafc05790f26c)
cli_ret "${result}" "burn"
sleep 4
# eth 这端 金额是否减少了 1
result=$(${CLIA} ethereum balance -o "${ethTestAddr1}" -t "${ethereumZbcBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "1"
sleep ${maturityDegree}
# 接收的地址金额 变成了 8
result=$(${Chain33Cli} evm query -a "${chain33ZbcERC20TokenAddr}" -c "${chain33ReceiverAddr}" -b "balanceOf(${chain33ReceiverAddr})")
is_equal "${result}" "800000000"
# chain33BridgeBank 是否减少了 1
result=$(${Chain33Cli} evm query -a "${chain33ZbcERC20TokenAddr}" -c "${chain33BridgeBank}" -b "balanceOf(${chain33BridgeBank})")
is_equal "${result}" "100000000"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# eth to chain33 在以太坊上锁定 ETH 资产,然后在 chain33 上 burn
function TestETH2Chain33Assets() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== eth to chain33 在以太坊上锁定 ETH 资产,然后在 chain33 上 burn ===========${NOC}"
# 查询 ETH 这端 bridgeBank 地址原来是 0
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
cli_ret "${result}" "balance" ".balance" "0"
# ETH 这端 lock 11个
result=$(${CLIA} ethereum lock -m 11 -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}")
cli_ret "${result}" "lock"
# eth 等待 2 个区块
sleep 4
# 查询 ETH 这端 bridgeBank 地址 11
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
cli_ret "${result}" "balance" ".balance" "11"
sleep ${maturityDegree}
# chain33 chain33EthBridgeTokenAddr(ETH合约中)查询 lock 金额
result=$(${Chain33Cli} evm query -a "${chain33EthBridgeTokenAddr}" -c "${chain33DeployAddr}" -b "balanceOf(${chain33ReceiverAddr})")
# 结果是 11 * le8
is_equal "${result}" "1100000000"
# 原来的数额
result=$(${CLIA} ethereum balance -o "${ethTestAddr2}")
cli_ret "${result}" "balance" ".balance" "1000"
echo '#5.burn ETH from Chain33 ETH(Chain33)-----> Ethereum'
result=$(${CLIA} chain33 burn -m 5 -k "${chain33ReceiverAddrKey}" -r "${ethTestAddr2}" -t "${chain33EthBridgeTokenAddr}")
cli_ret "${result}" "burn"
sleep ${maturityDegree}
echo "check the balance on chain33"
result=$(${Chain33Cli} evm query -a "${chain33EthBridgeTokenAddr}" -c "${chain33DeployAddr}" -b "balanceOf(${chain33ReceiverAddr})")
# 结果是 11-5 * le8
is_equal "${result}" "600000000"
# 查询 ETH 这端 bridgeBank 地址 0
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
cli_ret "${result}" "balance" ".balance" "6"
# 比之前多 5
result=$(${CLIA} ethereum balance -o "${ethTestAddr2}")
cli_ret "${result}" "balance" ".balance" "1005"
echo '#5.burn ETH from Chain33 ETH(Chain33)-----> Ethereum 6'
result=$(${CLIA} chain33 burn -m 6 -k "${chain33ReceiverAddrKey}" -r "${ethTestAddr2}" -t "${chain33EthBridgeTokenAddr}")
cli_ret "${result}" "burn"
sleep ${maturityDegree}
echo "check the balance on chain33"
result=$(${Chain33Cli} evm query -a "${chain33EthBridgeTokenAddr}" -c "${chain33DeployAddr}" -b "balanceOf(${chain33ReceiverAddr})")
# 结果是 11-5 * le8
is_equal "${result}" "0"
# 查询 ETH 这端 bridgeBank 地址 0
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
cli_ret "${result}" "balance" ".balance" "0"
# 比之前多 5
result=$(${CLIA} ethereum balance -o "${ethTestAddr2}")
cli_ret "${result}" "balance" ".balance" "1011"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function TestETH2Chain33Ycc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== eth to chain33 在以太坊上锁定 ycc 资产,然后在 chain33 上 burn ===========${NOC}"
# 查询 ETH 这端 bridgeBank 地址原来是 0
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "0"
# ETH 这端 lock 7个 YCC
result=$(${CLIA} ethereum lock -m 7 -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "lock"
# eth 等待 2 个区块
sleep 4
# 查询 ETH 这端 bridgeBank 地址 7 YCC
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "7"
sleep ${maturityDegree}
# chain33 chain33EthBridgeTokenAddr(ETH合约中)查询 lock 金额
result=$(${Chain33Cli} evm query -a "${chain33BycBridgeTokenAddr}" -c "${chain33TestAddr1}" -b "balanceOf(${chain33ReceiverAddr})")
# 结果是 7 * le8
is_equal "${result}" "700000000"
# 原来的数额 0
result=$(${CLIA} ethereum balance -o "${ethReceiverAddr1}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "0"
echo '#5.burn YCC from Chain33 YCC(Chain33)-----> Ethereum'
result=$(${CLIA} chain33 burn -m 5 -k "${chain33ReceiverAddrKey}" -r "${ethReceiverAddr1}" -t "${chain33BycBridgeTokenAddr}")
cli_ret "${result}" "burn"
sleep ${maturityDegree}
echo "check the balance on chain33"
result=$(${Chain33Cli} evm query -a "${chain33BycBridgeTokenAddr}" -c "${chain33TestAddr1}" -b "balanceOf(${chain33ReceiverAddr})")
# 结果是 7-5 * le8
is_equal "${result}" "200000000"
# 查询 ETH 这端 bridgeBank 地址 2
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "2"
# 更新后的金额 5
result=$(${CLIA} ethereum balance -o "${ethReceiverAddr1}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "5"
echo '#5.burn YCC from Chain33 YCC(Chain33)-----> Ethereum'
result=$(${CLIA} chain33 burn -m 2 -k "${chain33ReceiverAddrKey}" -r "${ethReceiverAddr1}" -t "${chain33BycBridgeTokenAddr}")
cli_ret "${result}" "burn"
sleep ${maturityDegree}
echo "check the balance on chain33"
result=$(${Chain33Cli} evm query -a "${chain33BycBridgeTokenAddr}" -c "${chain33TestAddr1}" -b "balanceOf(${chain33ReceiverAddr})")
# 结果是 7-5 * le8
is_equal "${result}" "0"
# 查询 ETH 这端 bridgeBank 地址 0
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "0"
# 更新后的金额 5
result=$(${CLIA} ethereum balance -o "${ethReceiverAddr1}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "7"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# shellcheck disable=SC2120
function offline_set_offline_token_Bty() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== chain33 端 configLockedTokenOfflineSave BTY ======${NOC}"
# echo '2:#配置自动转离线钱包(bty, 100, 50%)'
local threshold=10000000000
local percents=50
if [[ $# -eq 2 ]]; then
threshold=$1
percents=$2
fi
# shellcheck disable=SC2086
${Boss4xCLI} chain33 offline set_offline_token -c "${chain33BridgeBank}" -s BTY -m ${threshold} -p ${percents} -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "chain33_set_offline_token.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# shellcheck disable=SC2120
function offline_set_offline_token_Chain33Ycc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== chain33 端 configLockedTokenOfflineSave ERC20 YCC ======${NOC}"
# echo '2:#配置自动转离线钱包(YCC, 100, 60%)'
local threshold=10000000000
local percents=60
if [[ $# -eq 2 ]]; then
threshold=$1
percents=$2
fi
# shellcheck disable=SC2086
${Boss4xCLI} chain33 offline set_offline_token -c "${chain33BridgeBank}" -t "${chain33YccERC20TokenAddr}" -s YCC -m ${threshold} -p ${percents} -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "chain33_set_offline_token.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# shellcheck disable=SC2120
function offline_set_offline_token_Eth() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# echo '2:#配置自动转离线钱包(eth, 20, 50%)'
local threshold=20
local percents=50
if [[ $# -eq 2 ]]; then
threshold=$1
percents=$2
fi
# shellcheck disable=SC2086
${Boss4xCLI} ethereum offline set_offline_token -s ETH -m ${threshold} -p ${percents} -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "set_offline_token.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# shellcheck disable=SC2120
function offline_set_offline_token_EthYcc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
local threshold=100
local percents=40
if [[ $# -eq 2 ]]; then
threshold=$1
percents=$2
fi
# shellcheck disable=SC2086
${Boss4xCLI} ethereum offline set_offline_token -s BYC -m ${threshold} -p ${percents} -t "${ethereumBycERC20TokenAddr}" -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "set_offline_token.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function offline_transfer_multisign_Bty_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# transfer test
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline create_multisign_transfer -a 50 -r "${chain33BridgeBank}" -m "${multisignChain33Addr}"
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline multisign_transfer -k "${chain33DeployKey}" -s "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" --chainID "${chain33ID}"
chain33_offline_send "multisign_transfer.txt"
sleep 10
result=$(${Chain33Cli} asset balance -a "${chain33BridgeBank}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "103.2500"
result=$(${Chain33Cli} asset balance -a "${multisignChain33Addr}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "59.7500"
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline create_multisign_transfer -a 10 -r "${chain33MultisignA}" -m "${multisignChain33Addr}"
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline multisign_transfer -k "${chain33DeployKey}" -s "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" --chainID "${chain33ID}"
chain33_offline_send "multisign_transfer.txt"
sleep 10
result=$(${Chain33Cli} asset balance -a "${chain33MultisignA}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "10.0000"
result=$(${Chain33Cli} asset balance -a "${multisignChain33Addr}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "49.7500"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function coins_cross_transfer() {
local key="${1}"
local addr="${2}"
local amount="${3}"
local para_amount="${4}"
local evm_amount="${5}"
# 先把 bty 转入到 paracross 合约中
hash=$(${MainCli} send coins send_exec -e paracross -a "${amount}" -k "${key}")
check_tx "${MainCli}" "${hash}"
# 主链中的 bty 夸链到 平行链中
hash=$(${Para8801Cli} send para cross_transfer -a "${para_amount}" -e coins -s bty -t "${addr}" -k "${key}")
check_tx "${Para8801Cli}" "${hash}"
check_tx "${Para8901Cli}" "${hash}"
result=$(${Para8901Cli} asset balance -a "${addr}" --asset_exec paracross --asset_symbol coins.bty | jq -r .balance)
is_equal "${result}" "${para_amount}.0000"
# 把平行链中的 bty 转入 平行链中的 evm 合约
hash=$(${Para8901Cli} send para transfer_exec -a "${evm_amount}" -e user.p.para.evm -s coins.bty -k "${key}")
check_tx "${Para8901Cli}" "${hash}"
result=$(${Para8901Cli} asset balance -a "${addr}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "${evm_amount}.0000"
}
function initPara() {
# para add
hash=$(${Para8901Cli} send coins transfer -a 10000 -n test -t "${chain33ReceiverAddr}" -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944)
check_tx "${Para8901Cli}" "${hash}"
Chain33Cli=${Para8901Cli}
InitChain33Validator
coins_cross_transfer "${chain33DeployKey}" "${chain33DeployAddr}" 1000 800 500
coins_cross_transfer "${chain33TestAddrKey1}" "${chain33TestAddr1}" 1000 800 500
coins_cross_transfer "${chain33TestAddrKey2}" "${chain33TestAddr2}" 1000 800 500
}
# lock bty 判断是否转入多签地址金额是否正确
function lock_bty_multisign_docker() {
local lockAmount=$1
local lockAmount2="${1}00000000"
hash=$(${Chain33Cli} send evm call -f 1 -a "${lockAmount}" -k "${chain33TestAddr1}" -e "${chain33BridgeBank}" -p "lock(${ethTestAddr1}, ${chain33BtyERC20TokenAddr}, ${lockAmount2})" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
if [[ $# -eq 3 ]]; then
local bridgeBankBalance=$2
local multisignBalance=$3
result=$(${Chain33Cli} asset balance -a "${chain33BridgeBank}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "${bridgeBankBalance}"
result=$(${Chain33Cli} asset balance -a "${multisignChain33Addr}" --asset_exec paracross --asset_symbol coins.bty -e user.p.para.evm | jq -r .balance)
is_equal "${result}" "${multisignBalance}"
fi
}
function lockBty() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== chain33 端 lock BTY ======${NOC}"
# echo '2:#配置自动转离线钱包(bty, 100, 50%)'
offline_set_offline_token_Bty
lock_bty_multisign_docker 33 "33.0000" "0.0000"
lock_bty_multisign_docker 80 "56.5000" "56.5000"
lock_bty_multisign_docker 50 "53.2500" "109.7500"
# transfer test
offline_transfer_multisign_Bty_test
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lockChain33Ycc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== chain33 端 lock ERC20 YCC ======${NOC}"
# echo '2:#配置自动转离线钱包(YCC, 100, 60%)'
offline_set_offline_token_Chain33Ycc
lock_chain33_ycc_multisign 30 30 0
lock_chain33_ycc_multisign 70 40 60
lock_chain33_ycc_multisign 260 120 240
lock_chain33_ycc_multisign 10 52 318
# transfer test
offline_transfer_multisign_Chain33Ycc_test
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lockEth() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== ethereum 端 lock ETH ======${NOC}"
# echo '2:#配置自动转离线钱包(eth, 20, 50%)'
offline_set_offline_token_Eth
# 重启 nonce 会不统一 要重启一下
restart_ebrelayerA
lock_eth_multisign 19 19 0
lock_eth_multisign 1 10 10
lock_eth_multisign 16 13 23
# transfer
# shellcheck disable=SC2154
offline_transfer_multisign_Eth_test
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lockEthYcc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== ethereum 端 lock ERC20 YCC ======${NOC}"
# echo '2:#配置自动转离线钱包(ycc, 100, 40%)'
offline_set_offline_token_EthYcc
# 重启 nonce 会不统一 要重启一下
restart_ebrelayerA
lock_ethereum_ycc_multisign 70 70 0
lock_ethereum_ycc_multisign 30 60 40
lock_ethereum_ycc_multisign 60 72 88
# multisignEthAddr 要有手续费
${CLIA} ethereum transfer -k "${ethDeployKey}" -m 10 -r "${multisignEthAddr}"
sleep 10
# transfer
offline_transfer_multisign_EthYcc
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function StartDockerRelayerDeploy() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# 修改 relayer.toml 配置文件 pushName 字段
pushNameChange "./relayer.toml"
# 修改 relayer.toml 配置文件 initPowers
validators_config
# change EthProvider url
dockerAddr=$(get_docker_addr "${dockerNamePrefix}_ganachetest_1")
# 修改 relayer.toml 配置文件
updata_relayer_a_toml "${dockerAddr}" "${dockerNamePrefix}_ebrelayera_1" "./relayer.toml"
# 删除私钥
delete_line "./relayer.toml" "deployerPrivateKey="
delete_line "./relayer.toml" "deployerPrivateKey="
# para
# shellcheck disable=SC2155
local line=$(delete_line_show "./relayer.toml" "chain33Host")
# 在第 line 行后面 新增合约地址
docker_chain33_ip=$(get_docker_addr "${dockerNamePrefix}_chain33_1")
sed -i ''"${line}"' a chain33Host="http://'"${docker_chain33_ip}"':8901"' "./relayer.toml"
# shellcheck disable=SC2155
local line=$(delete_line_show "./relayer.toml" "ChainName")
# 在第 line 行后面 新增合约地址
sed -i ''"${line}"' a ChainName="user.p.para."' "./relayer.toml"
# shellcheck disable=SC2155
local line=$(delete_line_show "./relayer.toml" "maturityDegree=10")
sed -i ''"${line}"' a maturityDegree=1' "./relayer.toml"
# shellcheck disable=SC2155
local line=$(delete_line_show "./relayer.toml" "EthMaturityDegree=10")
sed -i ''"${line}"' a EthMaturityDegree=1' "./relayer.toml"
# 启动 ebrelayer
start_docker_ebrelayerA
# 部署合约 设置 bridgeRegistry 地址
InitAndOfflineDeploy
# 设置离线多签数据
Chain33Cli=${MainCli}
initMultisignChain33Addr
Chain33Cli=${Para8901Cli}
offline_setupChain33Multisign
offline_setupEthMultisign
Chain33Cli=${MainCli}
transferChain33MultisignFee
Chain33Cli=${Para8901Cli}
# shellcheck disable=SC2086
{
docker cp "${BridgeRegistryOnChain33}.abi" "${dockerNamePrefix}_ebrelayera_1":/root/${BridgeRegistryOnChain33}.abi
docker cp "${chain33BridgeBank}.abi" "${dockerNamePrefix}_ebrelayera_1":/root/${chain33BridgeBank}.abi
docker cp "${BridgeRegistryOnEth}.abi" "${dockerNamePrefix}_ebrelayera_1":/root/${BridgeRegistryOnEth}.abi
docker cp "${ethBridgeBank}.abi" "${dockerNamePrefix}_ebrelayera_1":/root/${ethBridgeBank}.abi
}
# 重启
restart_ebrelayerA
# start ebrelayer B C D
updata_toml_start_bcd
# 设置 token 地址
# InitTokenAddr
offline_create_bridge_token_eth_BTY
offline_create_bridge_token_chain33_ETH
offline_deploy_erc20_eth_BYC
offline_create_bridge_token_chain33_BYC
offline_deploy_erc20_chain33_YCC
offline_create_bridge_token_eth_YCC
offline_deploy_erc20_chain33_ZBC
offline_create_bridge_token_eth_ZBC
# shellcheck disable=SC2086
{
docker cp "${chain33EthBridgeTokenAddr}.abi" "${dockerNamePrefix}_ebrelayera_1":/root/${chain33EthBridgeTokenAddr}.abi
docker cp "${chain33BycBridgeTokenAddr}.abi" "${dockerNamePrefix}_ebrelayera_1":/root/${chain33BycBridgeTokenAddr}.abi
docker cp "${chain33YccERC20TokenAddr}.abi" "${dockerNamePrefix}_ebrelayera_1":/root/${chain33YccERC20TokenAddr}.abi
docker cp "${ethereumYccBridgeTokenAddr}.abi" "${dockerNamePrefix}_ebrelayera_1":/root/${ethereumYccBridgeTokenAddr}.abi
}
# 重启,因为relayerA的验证人地址和部署人的地址是一样的,所以需要重新启动relayer,更新nonce
restart_ebrelayerA
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function echo_addrs() {
echo -e "${GRE}=========== echo contract addrs ===========${NOC}"
echo -e "${GRE}BridgeRegistryOnChain33: ${BridgeRegistryOnChain33} ${NOC}"
echo -e "${GRE}BridgeRegistryOnEth: ${BridgeRegistryOnEth} ${NOC}"
echo -e "${GRE}chain33BridgeBank: ${chain33BridgeBank} ${NOC}"
echo -e "${GRE}ethBridgeBank: ${ethBridgeBank} ${NOC}"
echo -e "${GRE}chain33BtyERC20TokenAddr: ${chain33BtyERC20TokenAddr} ${NOC}"
echo -e "${GRE}chain33EthBridgeTokenAddr: ${chain33EthBridgeTokenAddr} ${NOC}"
echo -e "${GRE}ethereumBtyBridgeTokenAddr: ${ethereumBtyBridgeTokenAddr} ${NOC}"
echo -e "${GRE}chain33BycBridgeTokenAddr: ${chain33BycBridgeTokenAddr} ${NOC}"
echo -e "${GRE}ethereumBycERC20TokenAddr: ${ethereumBycERC20TokenAddr} ${NOC}"
echo -e "${GRE}chain33YccERC20TokenAddr: ${chain33YccERC20TokenAddr} ${NOC}"
echo -e "${GRE}ethereumYccBridgeTokenAddr: ${ethereumYccBridgeTokenAddr} ${NOC}"
echo -e "${GRE}chain33ZbcERC20TokenAddr: ${chain33ZbcERC20TokenAddr} ${NOC}"
echo -e "${GRE}ethereumZbcBridgeTokenAddr: ${ethereumZbcBridgeTokenAddr} ${NOC}"
echo -e "${GRE}multisignChain33Addr: ${multisignChain33Addr} ${NOC}"
echo -e "${GRE}multisignEthAddr: ${multisignEthAddr} ${NOC}"
echo -e "${GRE}XgoBridgeRegistryOnChain33: ${XgoBridgeRegistryOnChain33} ${NOC}"
echo -e "${GRE}XgoChain33BridgeBank: ${XgoChain33BridgeBank} ${NOC}"
echo -e "${GRE}=========== echo don't use addrs ===========${NOC}"
echo -e "${GRE}ethDeployAddr: ${ethDeployAddr} ${NOC}"
echo -e "${GRE}chain33DeployAddr: ${chain33DeployAddr} ${NOC}"
echo -e "${GRE}chain33ValidatorA: ${chain33Validatora} ${NOC}"
echo -e "${GRE}chain33ValidatorB: ${chain33Validatorb} ${NOC}"
echo -e "${GRE}chain33ValidatorC: ${chain33Validatorc} ${NOC}"
echo -e "${GRE}chain33ValidatorD: ${chain33Validatord} ${NOC}"
echo -e "${GRE}ethValidatorAddrA: ${ethValidatorAddra} ${NOC}"
echo -e "${GRE}ethValidatorAddrB: ${ethValidatorAddrb} ${NOC}"
echo -e "${GRE}ethValidatorAddrC: ${ethValidatorAddrc} ${NOC}"
echo -e "${GRE}ethValidatorAddrD: ${ethValidatorAddrd} ${NOC}"
echo -e "${GRE}=========== echo use test addrs and keys===========${NOC}"
echo -e "${GRE}ethTestAddr1: ${ethTestAddr1} ${NOC}"
echo -e "${GRE}ethTestAddrKey1: ${ethTestAddrKey1} ${NOC}"
echo -e "${GRE}chain33TestAddr1: ${chain33TestAddr1} ${NOC}"
echo -e "${GRE}chain33TestAddrKey1: ${chain33TestAddrKey1} ${NOC}"
}
function chain33_offline_send_evm() {
# shellcheck disable=SC2154
result=$(${EvmxgoBoss4xCLI} chain33 offline send -f "${1}")
hash=$(echo "${result}" | jq -r ".[0].TxHash")
# shellcheck disable=SC2154
check_tx "${Chain33Cli}" "${hash}"
}
function DeployEvmxgo() {
# 在 chain33 上部署合约
# shellcheck disable=SC2154
${EvmxgoBoss4xCLI} chain33 offline create -f 1 -k "${chain33DeployKey}" -n "deploy crossx to chain33" -r "${chain33DeployAddr}, [${chain33Validatora}, ${chain33Validatorb}, ${chain33Validatorc}, ${chain33Validatord}], [96, 1, 1, 1]" --chainID "${chain33ID}"
result=$(${EvmxgoBoss4xCLI} chain33 offline send -f "deployBridgevmxgo2Chain33.txt")
for i in {0..6}; do
hash=$(echo "${result}" | jq -r ".[$i].TxHash")
check_tx "${Chain33Cli}" "${hash}"
done
XgoBridgeRegistryOnChain33=$(echo "${result}" | jq -r ".[6].ContractAddr")
# 拷贝 BridgeRegistry.abi 和 BridgeBank.abi
cp XgoBridgeRegistryOnChain33.abi "${XgoBridgeRegistryOnChain33}.abi"
XgoChain33BridgeBank=$(${Chain33Cli} evm query -c "${chain33DeployAddr}" -b "bridgeBank()" -a "${XgoBridgeRegistryOnChain33}")
cp XgoChain33BridgeBank.abi "${XgoChain33BridgeBank}.abi"
${EvmxgoBoss4xCLI} chain33 offline create_add_lock_list -s ETH -t "${chain33EthBridgeTokenAddr}" -c "${XgoChain33BridgeBank}" -k "${chain33DeployKey}" -f 1 --chainID "${chain33ID}"
chain33_offline_send_evm "create_add_lock_list.txt"
${EvmxgoBoss4xCLI} chain33 offline create_add_lock_list -s BYC -t "${chain33BycBridgeTokenAddr}" -c "${XgoChain33BridgeBank}" -k "${chain33DeployKey}" -f 1 --chainID "${chain33ID}"
chain33_offline_send_evm "create_add_lock_list.txt"
# 重启,需要重新启动relayer,更新nonce
restart_ebrelayerA
}
# $1 symbol $2 bridgeTokenAddr
function updateConfig() {
local symbol=$1
local bridgeTokenAddr=$2
tx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.CreateTransaction","params":[{"execer":"manage","actionName":"Modify","payload":{"key":"evmxgo-mint-'"${symbol}"'","value":"{\"address\":\"'"${bridgeTokenAddr}"'\",\"precision\":8,\"introduction\":\"symbol:'"${symbol}"', bridgeTokenAddr:'"${bridgeTokenAddr}"'\"}","op":"add","addr":""}}]}' -H 'content-type:text/plain;' "http://127.0.0.1:8901" | jq -r ".result")
if [ "${tx}" == "" ]; then
echo -e "${RED}update config create tx 1${NOC}"
exit 1
fi
sign=$(${Chain33Cli} wallet sign -k "$chain33ReceiverAddrKey" -d "${tx}")
hash=$(${Chain33Cli} wallet send -d "${sign}")
check_tx "${Chain33Cli}" "${hash}"
}
function configbridgevmxgoAddr() {
local bridgevmxgoAddr=$1
tx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.CreateTransaction","params":[{"execer":"manage","actionName":"Modify","payload":{"key":"bridgevmxgo-contract-addr","value":"{\"address\":\"'"${bridgevmxgoAddr}"'\"}","op":"add","addr":""}}]}' -H 'content-type:text/plain;' "http://127.0.0.1:8901" | jq -r ".result")
if [ "${tx}" == "" ]; then
echo -e "${RED}update config create tx 1${NOC}"
exit 1
fi
sign=$(${Chain33Cli} wallet sign -k "$chain33ReceiverAddrKey" -d "${tx}")
hash=$(${Chain33Cli} wallet send -d "${sign}")
check_tx "${Chain33Cli}" "${hash}"
}
function TestETH2EVMToChain33() {
# 查询 ETH 这端 bridgeBank 地址原来是 0
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
# cli_ret "${result}" "balance" ".balance" "16"
# ETH 这端 lock 11个
result=$(${CLIA} ethereum lock -m 11 -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}")
# cli_ret "${result}" "lock"
# eth 等待 2 个区块
sleep 4
# 查询 ETH 这端 bridgeBank 地址 11 原来16
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
# cli_ret "${result}" "balance" ".balance" "27"
sleep ${maturityDegree}
# chain33 chain33EthBridgeTokenAddr(ETH合约中)查询 lock 金额
result=$(${Chain33Cli} evm query -a "${chain33EthBridgeTokenAddr}" -c "${chain33DeployAddr}" -b "balanceOf(${chain33ReceiverAddr})")
# 结果是 11 * le8
# is_equal "${result}" "4700000000"
updateConfig "ETH" "${chain33EthBridgeTokenAddr}"
configbridgevmxgoAddr "${XgoChain33BridgeBank}"
${EvmxgoBoss4xCLI} chain33 offline approve_erc20 -a 330000000000 -s "${XgoChain33BridgeBank}" -c "${chain33EthBridgeTokenAddr}" -k "${chain33ReceiverAddrKey}" -f 1 --chainID "${chain33ID}"
chain33_offline_send_evm "approve_erc20.txt"
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33ReceiverAddr}" -e "${XgoChain33BridgeBank}" -p "lock(${chain33TestAddr2}, ${chain33EthBridgeTokenAddr}, 500000000)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
result=$(${Chain33Cli} evm query -a "${chain33EthBridgeTokenAddr}" -c "${chain33DeployAddr}" -b "balanceOf(${chain33ReceiverAddr})")
# is_equal "${result}" "4200000000"
result=$(${Chain33Cli} evm query -a "${chain33EthBridgeTokenAddr}" -c "${chain33DeployAddr}" -b "balanceOf(${XgoChain33BridgeBank})")
# is_equal "${result}" "500000000"
}
function Testethereum2EVMToChain33_byc() {
# 查询 ETH 这端 bridgeBank 地址原来是
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
# cli_ret "${result}" "balance" ".balance" "0"
# ETH 这端 lock 7个
result=$(${CLIA} ethereum lock -m 7 -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "lock"
# eth 等待 2 个区块
sleep 4
# 查询 ETH 这端 bridgeBank 地址 7
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
# cli_ret "${result}" "balance" ".balance" "7"
sleep ${maturityDegree}
# chain33 chain33EthBridgeTokenAddr(ETH合约中)查询 lock 金额
result=$(${Chain33Cli} evm query -a "${chain33BycBridgeTokenAddr}" -c "${chain33TestAddr1}" -b "balanceOf(${chain33ReceiverAddr})")
# 结果是 7 * le8
# is_equal "${result}" "700000000"
updateConfig "BYC" "${chain33BycBridgeTokenAddr}"
configbridgevmxgoAddr "${XgoChain33BridgeBank}"
${EvmxgoBoss4xCLI} chain33 offline approve_erc20 -a 330000000000 -s "${XgoChain33BridgeBank}" -c "${chain33BycBridgeTokenAddr}" -k "${chain33ReceiverAddrKey}" -f 1 --chainID "${chain33ID}"
chain33_offline_send_evm "approve_erc20.txt"
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33ReceiverAddr}" -e "${XgoChain33BridgeBank}" -p "lock(${chain33TestAddr2}, ${chain33BycBridgeTokenAddr}, 500000000)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
result=$(${Chain33Cli} evm query -a "${chain33BycBridgeTokenAddr}" -c "${chain33DeployAddr}" -b "balanceOf(${chain33ReceiverAddr})")
# is_equal "${result}" "4200000000"
result=$(${Chain33Cli} evm query -a "${chain33BycBridgeTokenAddr}" -c "${chain33DeployAddr}" -b "balanceOf(${XgoChain33BridgeBank})")
# is_equal "${result}" "500000000"
}
function AllRelayerMainTest() {
set +e
docker_chain33_ip=$(get_docker_addr "${dockerNamePrefix}_chain33_1")
MainCli="./chain33-cli --rpc_laddr http://${docker_chain33_ip}:8801"
Para8801Cli="./chain33-cli --rpc_laddr http://${docker_chain33_ip}:8901 --paraName user.p.para."
Para8901Cli="./chain33-cli --rpc_laddr http://${docker_chain33_ip}:8901 --paraName user.p.para."
# shellcheck disable=SC2034
{
CLIA="docker exec ${dockerNamePrefix}_ebrelayera_1 /root/ebcli_A"
CLIB="docker exec ${dockerNamePrefix}_ebrelayerb_1 /root/ebcli_A"
CLIC="docker exec ${dockerNamePrefix}_ebrelayerc_1 /root/ebcli_A"
CLID="docker exec ${dockerNamePrefix}_ebrelayerd_1 /root/ebcli_A"
docker_ganachetest_ip=$(get_docker_addr "${dockerNamePrefix}_ganachetest_1")
Boss4xCLI="docker exec ${dockerNamePrefix}_ebrelayera_1 /root/boss4x --rpc_laddr http://${docker_chain33_ip}:8901 --rpc_laddr_ethereum http://${docker_ganachetest_ip}:8545 --paraName user.p.para."
echo "${Boss4xCLI}"
}
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
if [[ ${1} != "" ]]; then
maturityDegree=${1}
echo -e "${GRE}maturityDegree is ${maturityDegree} ${NOC}"
fi
# shellcheck disable=SC2120
if [[ $# -ge 2 ]]; then
chain33ID="${2}"
fi
# init
Chain33Cli=${MainCli}
InitChain33Validator
# para add
initPara
Chain33Cli=${Para8901Cli}
StartDockerRelayerDeploy
# test
Chain33Cli=${Para8901Cli}
TestChain33ToEthAssets
TestETH2Chain33Assets
TestChain33ToEthZBCAssets
TestETH2Chain33Ycc
Chain33Cli=${Para8901Cli}
lockBty
lockChain33Ycc
lockEth
lockEthYcc
# 离线多签地址转入阈值设大
offline_set_offline_token_Bty 100000000000000 10
offline_set_offline_token_Chain33Ycc 100000000000000 10
offline_set_offline_token_Eth 100000000000000 10
offline_set_offline_token_EthYcc 100000000000000 10
EvmxgoBoss4xCLI="./evmxgoboss4x --rpc_laddr http://${docker_chain33_ip}:8901 --paraName user.p.para."
DeployEvmxgo
TestETH2EVMToChain33
# 平行链共识节点增加测试币
${MainCli} send coins transfer -a 1000 -n test -t "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" -k "${chain33ReceiverAddrKey}"
${MainCli} send coins transfer -a 1000 -n test -t "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR" -k "${chain33ReceiverAddrKey}"
${MainCli} send coins transfer -a 1000 -n test -t "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k" -k "${chain33ReceiverAddrKey}"
${MainCli} send coins transfer -a 1000 -n test -t "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" -k "${chain33ReceiverAddrKey}"
echo_addrs
Testethereum2EVMToChain33_byc
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
#!/usr/bin/env bash
/root/chain33 -f /root/chain33.toml &
# to wait nginx start
sleep 15
/root/chain33 -f "$PARAFILE"
#user nobody;
worker_processes 1;
events {
#worker_connections 1024 may not enough
worker_connections 204800;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 1000;
#gzip on;
upstream chain33url{
ip_hash;
server chain33:8802 weight=1;
#server chain30:8802 weight=1;
}
server {
listen 8803 http2;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#proxy_pass http://yankerp;
grpc_pass grpc://chain33url;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
#!/usr/bin/env bash
PARA_CLI="docker exec ${NODE3} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI2="docker exec ${NODE2} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI1="docker exec ${NODE1} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI4="docker exec ${NODE4} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI5="docker exec ${NODE5} /root/chain33-cli --paraName user.p.game. --rpc_laddr http://localhost:8901"
#MAIN_CLI="docker exec ${NODE3} /root/chain33-cli"
PARANAME="para"
PARANAME_GAME="game"
#PARA_COIN_FROZEN="5.0000"
MainLoopCheckForkHeight="60"
#BLSPUB_E5="8920442cf306fccd11e7bde3cfffe183a138a941f471df0818edff5580b3ad7df42850a5cec15e09aef0fdd4489f7c12"
#BLSPUB_KS="a3d97d4186c80268fe6d3689dd574599e25df2dffdcff03f7d8ef64a3bd483241b7d0985958990de2d373d5604caf805"
#BLSPUB_JR="81307df1fdde8f0e846ed1542c859c1e9daba2553e62e48db0877329c5c63fb86e70b9e2e83263da0eb7fcad275857f8"
#BLSPUB_NL="ad1d9ff67d790581fa3659c1817985eeec7c65206e8a873147cd5b6bfe1356d5cd4ed1089462bd11e51705e100c95a6b"
#BLSPUB_MC="980287e26d4d44f8c57944ffc096f7d98a460c97dadbffaed14ff0de901fa7f8afc59fcb1805a0b031e5eae5601df1c2"
xsedfix=""
if [ "$(uname)" == "Darwin" ]; then
xsedfix=".bak"
fi
# shellcheck source=/dev/null
#source test-rpc.sh
function para_init() {
para_set_toml chain33.para33.toml "$PARANAME" "$1"
para_set_toml chain33.para32.toml "$PARANAME" "$1"
para_set_toml chain33.para31.toml "$PARANAME" "$1"
para_set_toml chain33.para30.toml "$PARANAME" "$1"
sed -i $xsedfix 's/^authAccount=.*/authAccount="1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"/g' chain33.para33.toml
sed -i $xsedfix 's/^authAccount=.*/authAccount="1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"/g' chain33.para32.toml
sed -i $xsedfix 's/^authAccount=.*/authAccount="1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"/g' chain33.para31.toml
sed -i $xsedfix 's/^authAccount=.*/authAccount="1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"/g' chain33.para30.toml
para_set_toml chain33.para29.toml "$PARANAME_GAME" "$1"
sed -i $xsedfix 's/^authAccount=.*/authAccount="1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"/g' chain33.para29.toml
}
function para_set_toml() {
cp chain33.para.toml "${1}"
local paraname="$2"
sed -i $xsedfix 's/^Title.*/Title="user.p.'''"$paraname"'''."/g' "${1}"
sed -i $xsedfix 's/^# TestNet=.*/TestNet=true/g' "${1}"
sed -i $xsedfix 's/^startHeight=.*/startHeight=1/g' "${1}"
sed -i $xsedfix 's/^emptyBlockInterval=.*/emptyBlockInterval=["0:4"]/g' "${1}"
sed -i $xsedfix 's/^mainForkParacrossCommitTx=.*/mainForkParacrossCommitTx=10/g' "${1}"
sed -i $xsedfix 's/^mainLoopCheckCommitTxDoneForkHeight=.*/mainLoopCheckCommitTxDoneForkHeight='''$MainLoopCheckForkHeight'''/g' "${1}"
sed -i $xsedfix 's/^mainBlockHashForkHeight=.*/mainBlockHashForkHeight=1/g' "${1}"
sed -i $xsedfix 's/^unBindTime=.*/unBindTime=0/g' "${1}"
#blsSign case
if [ -n "$3" ]; then
echo "${1} blssign=$3"
sed -i $xsedfix '/types=\["dht"\]/!b;n;cenable=true' "${1}"
sed -i $xsedfix '/emptyBlockInterval=/!b;n;cblsSign=true' "${1}"
sed -i $xsedfix '/blsSign=/!b;n;cblsLeaderSwitchIntval=10' "${1}"
fi
#blockchain
sed -i $xsedfix 's/^enableReduceLocaldb=.*/enableReduceLocaldb=false/g' "${1}"
sed -i $xsedfix 's/^enablePushSubscribe=.*/enablePushSubscribe=true/g' "${1}"
# rpc
sed -i $xsedfix 's/^jrpcBindAddr=.*/jrpcBindAddr="0.0.0.0:8901"/g' "${1}"
sed -i $xsedfix 's/^grpcBindAddr=.*/grpcBindAddr="0.0.0.0:8902"/g' "${1}"
sed -i $xsedfix 's/^whitelist=.*/whitelist=["localhost","127.0.0.1","0.0.0.0"]/g' "${1}"
sed -i $xsedfix 's/^ParaRemoteGrpcClient=.*/ParaRemoteGrpcClient="nginx:8803"/g' "${1}"
sed -i $xsedfix 's/^genesis="1JmFaA6unrCFYEWP.*/genesis="1G5Cjy8LuQex2fuYv3gzb7B8MxAnxLEqt3"/g' "${1}"
# shellcheck disable=SC1004
sed -i $xsedfix 's/^superManager=.*/superManager=["1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",\
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",\
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"]/g' "${1}"
# shellcheck disable=SC1004
sed -i $xsedfix 's/^tokenApprs=.*/tokenApprs=[ "1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",\
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK",\
"1LY8GFia5EiyoTodMLfkB5PHNNpXRqxhyB",\
"1GCzJDS6HbgTQ2emade7mEJGGWFfA15pS9",\
"1JYB8sxi4He5pZWHCd3Zi2nypQ4JMB6AxN",\
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",]/g' "${1}"
#autonomy
sed -i $xsedfix 's/^useBalance=.*/useBalance=true/g' "${1}"
sed -i $xsedfix 's/^total="16htvcBNS.*/total="1EZrEKPPC36SLRoLQBwLDjzcheiLRZJg49"/g' "${1}"
sed -i $xsedfix 's/^ForkRootHash=.*/ForkRootHash=0/g' "${1}"
}
function para_set_wallet() {
echo "=========== # para set wallet ============="
para_import_wallet "${PARA_CLI}" "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" "paraAuthAccount"
para_import_wallet "${PARA_CLI2}" "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" "paraAuthAccount"
para_import_wallet "${PARA_CLI1}" "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" "paraAuthAccount"
para_import_wallet "${PARA_CLI4}" "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" "paraAuthAccount"
#14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
para_import_key "${PARA_CLI}" "0xCC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944" "genesis"
#12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
para_import_key "${PARA_CLI}" "0x4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01" "test"
#1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
para_import_key "${PARA_CLI}" "0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588" "relay"
#1PUiGcbsccfxW3zuvHXZBJfznziph5miAo
para_import_key "${PARA_CLI}" "0x56942AD84CCF4788ED6DACBC005A1D0C4F91B63BCF0C99A02BE03C8DEAE71138" "dapptest1"
#1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX
para_import_key "${PARA_CLI}" "0x2116459C0EC8ED01AA0EEAE35CAC5C96F94473F7816F114873291217303F6989" "dapptest2"
#1PcGKYYoLn1PLLJJodc1UpgWGeFAQasAkx
para_import_key "${PARA_CLI}" "9d315182e56fde7fadb94408d360203894e5134216944e858f9b31f70e9ecf40" "rpctestpooladdr"
#super node behalf test
#1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj
para_import_key "${PARA_CLI}" "0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5" "behalfnode"
#1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH
para_import_key "${PARA_CLI}" "0xfdf2bbff853ecff2e7b86b2a8b45726c6538ca7d1403dc94e50131ef379bdca0" "othernode1"
#1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB
para_import_key "${PARA_CLI}" "0x794443611e7369a57b078881445b93b754cbc9b9b8f526535ab9c6d21d29203d" "othernode2"
#cross_transfer
#1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
para_import_wallet "${PARA_CLI5}" "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" "paraAuthAccount"
#1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu
para_import_key "${PARA_CLI5}" "0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1" "cross_transfer"
}
function para_import_wallet() {
local lable=$3
echo "=========== # save seed to wallet ============="
result=$(${1} seed save -p 1314fuzamei -s "tortoise main civil member grace happy century convince father cage beach hip maid merry rib" | jq ".isok")
if [ "${result}" = "false" ]; then
echo "save seed to wallet error seed, result: ${result}"
exit 1
fi
echo "=========== # unlock wallet ============="
result=$(${1} wallet unlock -p 1314fuzamei -t 0 | jq ".isok")
if [ "${result}" = "false" ]; then
exit 1
fi
echo "=========== # import private key ============="
echo "key: ${2}"
result=$(${1} account import_key -k "${2}" -l "$lable" | jq ".label")
if [ -z "${result}" ]; then
exit 1
fi
echo "=========== # close auto mining ============="
result=$(${1} wallet auto_mine -f 0 | jq ".isok")
if [ "${result}" = "false" ]; then
exit 1
fi
echo "=========== # wallet status ============="
${1} wallet status
}
function para_import_key() {
local lable=$3
echo "=========== # import private key ============="
echo "key: ${2}"
result=$(${1} account import_key -k "${2}" -l "$lable" | jq ".label")
if [ -z "${result}" ]; then
exit 1
fi
}
function para_transfer() {
echo "=========== # para chain transfer ============="
main_transfer2account "1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
main_transfer2account "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
main_transfer2account "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
main_transfer2account "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
main_transfer2account "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
main_transfer2account "1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu"
# super node test
main_transfer2account "1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY"
main_transfer2account "1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj"
main_transfer2account "1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH" 10
main_transfer2account "1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB" 10
#relay test
main_transfer2account "1G5Cjy8LuQex2fuYv3gzb7B8MxAnxLEqt3" 10
main_transfer2account "1EZKahMRfoMiKp1BewjWrQWoaJ9kmC4hum" 10
#relay rpc test
para_transfer2account "${PARA_CLI}" "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
para_transfer2account "${PARA_CLI}" "1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY"
para_transfer2account "${PARA_CLI}" "1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"
para_transfer2account "${PARA_CLI}" "1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX"
#cross_transfer
#0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1
para_transfer2account "${PARA_CLI5}" "1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu"
#rpc test pool addr
para_transfer2account "${PARA_CLI}" "1PcGKYYoLn1PLLJJodc1UpgWGeFAQasAkx" 500000
block_wait "${CLI}" 2
echo "=========== # main chain send to paracross ============="
#1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY test
main_transfer2paracross "0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588"
#1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj
main_transfer2paracross "0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5" 100
block_wait "${CLI}" 2
echo "=========== # config token blacklist ============="
#token precreate
txhash=$(para_configkey "${PARA_CLI}" "token-blacklist" "BTY")
echo "txhash=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
}
function main_transfer2account() {
echo "${1}"
local coins=200
if [ "$#" -ge 2 ]; then
coins="$2"
fi
hash1=$(${CLI} send coins transfer -a "$coins" -n test -t "${1}" -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01)
echo "${hash1}"
}
function para_transfer2account() {
echo "${2}"
local coins=1000
if [ "$#" -ge 3 ]; then
coins="$3"
fi
hash1=$(${1} send coins transfer -a "$coins" -n transfer -t "${2}" -k 0xCC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944)
echo "${hash1}"
}
function main_transfer2paracross() {
echo "addr=${1}"
local coins=5
if [ "$#" -ge 2 ]; then
coins="$2"
fi
hash1=$(${CLI} send coins send_exec -a "$coins" -e paracross -k "${1}")
echo "${hash1}"
}
function para_configkey() {
tx=$(${1} config config_tx -o add -c "${2}" -v "${3}")
sign=$(${CLI} wallet sign -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc -d "${tx}")
send=$(${CLI} wallet send -d "${sign}")
echo "${send}"
}
function query_tx() {
set +x
local CLI=${1}
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong check_tx parameters${NOC}"
exit_cp_file
fi
if [[ ${2} == "" ]]; then
echo -e "${RED}wrong check_tx txHash is empty${NOC}"
exit_cp_file
fi
local count=0
while true; do
ty=$(${CLI} tx query -s "${2}" | jq .receipt.ty)
if [[ ${ty} != "" ]]; then
break
fi
count=$((count + 1))
sleep 1
if [[ ${count} -ge 100 ]]; then
echo "chain33 query tx for too long"
break
fi
done
set -x
ty=$(${CLI} tx query -s "${2}" | jq .receipt.ty)
if [[ ${ty} != 2 ]]; then
echo -e "${RED}check tx error, hash is ${2}${NOC}"
exit 1
# exit_cp_file
fi
# block_wait "${1}" 1
#
# local times=200
# while true; do
# ret=$(${1} tx query -s "${2}" | jq -r ".tx.hash")
# echo "query hash is ${2}, return ${ret} "
# if [ "${ret}" != "${2}" ]; then
# block_wait "${1}" 1
# times=$((times - 1))
# if [ $times -le 0 ]; then
# echo "query tx=$2 failed"
# exit 1
# fi
# else
# echo "query tx=$2 success"
# break
# fi
# done
}
function para_cross_transfer_from_parachain() {
echo "=========== # para cross transfer from parachain test ============="
balance=$(${PARA_CLI5} account balance -a 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu -e user.p.game.coins | jq -r ".balance")
if [ "${balance}" != "1000.0000" ]; then
echo "para account 1BM2xhBk should be 1000, real is $balance"
exit 1
fi
hash=$(${PARA_CLI5} send coins send_exec -e user.p.game.paracross -a 300 -k 0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1)
echo "${hash}"
query_tx "${PARA_CLI5}" "${hash}"
balance=$(${PARA_CLI5} account balance -a 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu -e user.p.game.paracross | jq -r ".balance")
if [ "${balance}" != "300.0000" ]; then
echo "para paracross account 1BM2xhBk should be 300, real is $balance"
exit 1
fi
echo "========== #1. user.p.game chain transfer to main chain 300 user.p.game.coins.para, remain=0 ==========="
hash=$(${PARA_CLI5} send para cross_transfer -a 300 -e user.p.game.coins -s para -t 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu -k 0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1)
echo "${hash}"
query_tx "${PARA_CLI5}" "${hash}"
check_cross_transfer_game_balance "300.0000" "0.0000" "${hash}"
echo "========== #2. main transfer 200 user.p.game.coins.para game chain asset to para chain, main remain=100, parachain=200 ===="
hash=$(${CLI} --paraName=user.p.para. send para cross_transfer -a 200 -e paracross -s user.p.game.coins.para -t 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu -k 0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1)
echo "${hash}"
query_tx "${CLI}" "${hash}"
check_cross_transfer_para_balance "100.0000" "200.0000" "${hash}"
echo "========== #3. withdraw game chain asset to main chain from para chain 50 user.p.game.coins.para,parachain=150,main=150 ===="
hash=$(${CLI} --paraName=user.p.para. send para cross_transfer -a 50 -e user.p.para.paracross -s paracross.user.p.game.coins.para -t 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu -k 0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1)
echo "${hash}"
query_tx "${CLI}" "${hash}"
check_cross_transfer_para_balance "150.0000" "150.0000" "${hash}"
echo "========== #4. withdraw game chain asset to game chain from main chain 50 user.p.game.coins.para,parachain=150,main=100,game=50 ======"
hash=$(${CLI} --paraName=user.p.game. send para cross_transfer -a 50 -e paracross -s user.p.game.coins.para -t 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu -k 0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1)
echo "${hash}"
query_tx "${CLI}" "${hash}"
check_cross_transfer_game_balance "100.0000" "50.0000" "${hash}"
}
function check_cross_transfer_para_balance() {
local times=200
local hash="$3"
while true; do
acc=$(${CLI} asset balance -a 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu --asset_exec paracross --asset_symbol user.p.game.coins.para -e paracross | jq -r ".balance")
acc_para=$(${PARA_CLI} asset balance -a 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu --asset_exec paracross --asset_symbol paracross.user.p.game.coins.para -e paracross | jq -r ".balance")
res=$(${CLI} para asset_txinfo -s "${hash}")
echo "$res"
succ=$(jq -r ".success" <<<"$res")
echo "main account balance is ${acc}, expect $1, para acct balance is ${acc_para},expect $2, cross rst=$succ, expect=true "
if [ "${acc}" != "$1" ] || [ "${acc_para}" != "$2" ] || [ "${succ}" != "true" ]; then
block_wait "${CLI}" 2
times=$((times - 1))
if [ $times -le 0 ]; then
echo "para_cross_transfer main chain to para chain failed"
${CLI} tx query -s "$hash"
${PARA_CLI} tx query -s "$hash"
exit 1
fi
else
echo "para_cross_transfer main chain to para chain success"
break
fi
done
}
function check_cross_transfer_game_balance() {
local times=200
local hash="$3"
while true; do
acc=$(${CLI} asset balance -a 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu --asset_exec paracross --asset_symbol user.p.game.coins.para -e paracross | jq -r ".balance")
acc_para=$(${PARA_CLI5} account balance -a 1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu -e user.p.game.paracross | jq -r ".balance")
res=$(${CLI} para asset_txinfo -s "${hash}")
echo "$res"
succ=$(jq -r ".success" <<<"$res")
echo "main account balance is ${acc}, expect $1, para exec acct balance is ${acc_para},expect $2, cross rst=$succ, expect=true "
if [ "${acc}" != "$1" ] || [ "${acc_para}" != "$2" ] || [ "${succ}" != "true" ]; then
block_wait "${CLI}" 2
times=$((times - 1))
if [ $times -le 0 ]; then
echo "para_cross_transfer main chain and game chain failed"
${CLI} tx query -s "$3"
${PARA_CLI5} tx query -s "$3"
exit 1
fi
else
echo "para_cross_transfer main chain and game chain success"
break
fi
done
}
function para_create_nodegroup() {
echo "=========== # para chain create node group again ============="
##apply
txhash=$(${PARA_CLI} send para nodegroup apply -a "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4,1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR,1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" -c 6 -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
balance=$(${CLI} account balance -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -e paracross | jq -r ".frozen")
# if [ "$balance" != "30.0000" ]; then
# echo "apply coinfrozen error balance=$balance"
## exit 1
# fi
echo "=========== # bridgevmxgo para chain approve node group ============="
##approve
txhash=$(${PARA_CLI} send para nodegroup approve -i "$id" -a "" -c 6 -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
status=$(${PARA_CLI} para nodegroup status | jq -r ".status")
if [ "$status" != 2 ]; then
echo "status not approve status=$status"
exit 1
fi
${PARA_CLI} para nodegroup addrs
}
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
set -x
set +e
source "./publicTest.sh"
source "./relayerPublic.sh"
# shellcheck disable=SC2120
function mainTest() {
kill_ebrelayer "chain33 -f"
sleep 2
# delete chain33 datadir
rm ../../datadir ../../logs -rf
local ganacheName=ganachetest
# shellcheck disable=SC2155
local isExit=$(docker inspect ${ganacheName} | jq ".[]" | jq ".Id")
if [[ ${isExit} != "" ]]; then
docker stop ${ganacheName}
docker rm ${ganacheName}
fi
kill_all_ebrelayer
cp ../../../plugin/dapp/cross2eth/ebrelayer/relayer.toml ./relayer.toml
}
mainTest "${1}"
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
set -x
set +e
# 只测试 lock 操作,不测试 burn
source "./publicTest.sh"
source "./relayerPublic.sh"
# ETH 部署合约者的私钥 用于部署合约时签名使用
ethDeployAddr="0x8afdadfc88a1087c9a1d6c0f5dd04634b87f303a"
ethDeployKey="8656d2bc732a8a816a461ba5e2d8aac7c7f85c26a813df30d5327210465eb230"
# chain33 部署合约者的私钥 用于部署合约时签名使用
chain33DeployAddr="1N6HstkyLFS8QCeVfdvYxx1xoryXoJtvvZ"
Chain33Cli="../../chain33-cli"
chain33BridgeBank=""
ethBridgeBank=""
chain33BtyERC20TokenAddr="1111111111111111111114oLvT2"
ethereumBycERC20TokenAddr=""
multisignChain33Addr=""
multisignEthAddr=""
ethereumYccBridgeTokenAddr=""
chain33YccERC20TokenAddr=""
CLIA="./ebcli_A"
chain33ID=0
function set_offline_token_Bty() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== chain33 端 configLockedTokenOfflineSave BTY ======${NOC}"
# echo '2:#配置自动转离线钱包(bty, 1000, 50%)'
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33BridgeBank}" -p "configLockedTokenOfflineSave(${chain33BtyERC20TokenAddr},BTY,100000000000,50)" --khainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lock_multisign_Bty_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
lock_bty_multisign 330 "330.0000" "0.0000"
lock_bty_multisign 800 "565.0000" "565.0000"
lock_bty_multisign 500 "532.5000" "1097.5000"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function transfer_multisign_Bty_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# transfer test
# shellcheck disable=SC2154
hash=$(${CLIA} chain33 multisign transfer -a 100 -r "${chain33BridgeBank}" -k "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" | jq -r ".msg")
check_tx "${Chain33Cli}" "${hash}"
sleep 2
result=$(${Chain33Cli} account balance -a "${multisignChain33Addr}" -e evm)
balance_ret "${result}" "997.5000"
result=$(${Chain33Cli} account balance -a "${chain33BridgeBank}" -e evm)
balance_ret "${result}" "632.5000"
# shellcheck disable=SC2154
hash=$(${CLIA} chain33 multisign transfer -a 100 -r "${chain33MultisignA}" -k "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" | jq -r ".msg")
check_tx "${Chain33Cli}" "${hash}"
sleep 2
result=$(${Chain33Cli} account balance -a "${multisignChain33Addr}" -e evm)
balance_ret "${result}" "897.5000"
result=$(${Chain33Cli} account balance -a "${chain33MultisignA}" -e evm)
balance_ret "${result}" "100.0000"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lockBty() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
set_offline_token_Bty
lock_multisign_Bty_test
transfer_multisign_Bty_test
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function set_offline_token_Chain33Ycc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== chain33 端 configLockedTokenOfflineSave ERC20 YCC ======${NOC}"
# echo '2:#配置自动转离线钱包(YCC, 100, 60%)'
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33BridgeBank}" -p "configLockedTokenOfflineSave(${chain33YccERC20TokenAddr},YCC,10000000000,60)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lock_multisign_Chain33Ycc_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
lock_chain33_ycc_multisign 30 30 0
lock_chain33_ycc_multisign 70 40 60
lock_chain33_ycc_multisign 260 120 240
lock_chain33_ycc_multisign 10 52 318
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function transfer_multisign_Chain33Ycc_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# transfer test
hash=$(${CLIA} chain33 multisign transfer -a 10 -r "${chain33BridgeBank}" -t "${chain33YccERC20TokenAddr}" -k "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" | jq -r ".msg")
check_tx "${Chain33Cli}" "${hash}"
sleep 2
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${chain33BridgeBank}" -b "balanceOf(${chain33BridgeBank})")
is_equal "${result}" "6200000000"
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${multisignChain33Addr}" -b "balanceOf(${multisignChain33Addr})")
is_equal "${result}" "30800000000"
hash=$(${CLIA} chain33 multisign transfer -a 5 -r "${chain33MultisignA}" -t "${chain33YccERC20TokenAddr}" -k "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" | jq -r ".msg")
check_tx "${Chain33Cli}" "${hash}"
sleep 2
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${chain33MultisignA}" -b "balanceOf(${chain33MultisignA})")
is_equal "${result}" "500000000"
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${multisignChain33Addr}" -b "balanceOf(${multisignChain33Addr})")
is_equal "${result}" "30300000000"
# 判断 ETH 这端是否金额一致
result=$(${CLIA} ethereum balance -o "${ethDeployAddr}" -t "${ethereumYccBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "370"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lockChain33Ycc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
set_offline_token_Chain33Ycc
lock_multisign_Chain33Ycc_test
transfer_multisign_Chain33Ycc_test
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function set_offline_token_Eth() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# echo '2:#配置自动转离线钱包(eth, 20, 50%)'
result=$(${CLIA} ethereum multisign set_offline_token -s ETH -m 20)
cli_ret "${result}" "set_offline_token -s ETH -m 20"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lock_multisign_Eth_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
cli_ret "${result}" "balance" ".balance" "0"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}")
cli_ret "${result}" "balance" ".balance" "0"
lock_eth_multisign 19 19 0
lock_eth_multisign 1 10 10
lock_eth_multisign 16 13 23
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function transfer_multisign_Eth_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# transfer
# shellcheck disable=SC2154
${CLIA} ethereum multisign transfer -a 3 -r "${ethBridgeBank}" -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
sleep 2
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
cli_ret "${result}" "balance" ".balance" "16"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}")
cli_ret "${result}" "balance" ".balance" "20"
# transfer
# shellcheck disable=SC2154
${CLIA} ethereum multisign transfer -a 5 -r "${ethMultisignA}" -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
sleep 2
result=$(${CLIA} ethereum balance -o "${ethMultisignA}")
cli_ret "${result}" "balance" ".balance" "105"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}")
cli_ret "${result}" "balance" ".balance" "15"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lockEth() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== ethereum 端 lock multisign ETH ======${NOC}"
set_offline_token_Eth
lock_multisign_Eth_test
transfer_multisign_Eth_test
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function set_offline_token_EthYcc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# echo '2:#配置自动转离线钱包(ycc, 100, 40%)'
result=$(${CLIA} ethereum multisign set_offline_token -s BYC -m 100 -p 40 -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "set_offline_token -s BYC -m 100"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lock_multisign_EthYcc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "0"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "0"
lock_ethereum_ycc_multisign 70 70 0
lock_ethereum_ycc_multisign 30 60 40
lock_ethereum_ycc_multisign 60 72 88
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function transfer_multisign_EthYcc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# transfer
# multisignEthAddr 要有手续费
${CLIA} ethereum transfer -k "${ethDeployKey}" -m 10 -r "${multisignEthAddr}"
sleep 2
# transfer
${CLIA} ethereum multisign transfer -a 8 -r "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}" -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
sleep 2
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "80"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "80"
# transfer
${CLIA} ethereum multisign transfer -a 10 -r "${ethMultisignA}" -t "${ethereumBycERC20TokenAddr}" -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
sleep 2
result=$(${CLIA} ethereum balance -o "${ethMultisignA}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "10"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "70"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function lockEthYcc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== ethereum 端 lock multisign YCC ======${NOC}"
set_offline_token_EthYcc
lock_multisign_EthYcc
transfer_multisign_EthYcc
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
set -x
set +e
# 主要在平行链上测试
source "./publicTest.sh"
source "./relayerPublic.sh"
# $1 send file
function chain33_offline_send() {
# shellcheck disable=SC2154
result=$(${Boss4xCLI} chain33 offline send -f "${1}")
hash=$(echo "${result}" | jq -r ".[0].TxHash")
# shellcheck disable=SC2154
check_tx "${Chain33Cli}" "${hash}"
}
# $1 send file $2 key
function ethereum_offline_sign_send() {
# shellcheck disable=SC2154
key="${ethDeployKey}"
if [[ ${2} != "" ]]; then
key="${2}"
fi
${Boss4xCLI} ethereum offline sign -f "${1}" -k "${key}"
result=$(${Boss4xCLI} ethereum offline send -f "deploysigntxs.txt")
hash=$(echo "${result}" | jq -r ".[0].TxHash")
check_eth_tx "${hash}"
}
# shellcheck disable=SC2120
function InitAndOfflineDeploy() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
result=$(${CLIA} set_pwd -p 123456hzj)
cli_ret "${result}" "set_pwd"
result=$(${CLIA} unlock -p 123456hzj)
cli_ret "${result}" "unlock"
# shellcheck disable=SC2154
result=$(${CLIA} chain33 import_privatekey -k "${chain33ValidatorKeya}")
cli_ret "${result}" "chain33 import_privatekey"
# shellcheck disable=SC2154
result=$(${CLIA} ethereum import_privatekey -k "${ethValidatorAddrKeya}")
cli_ret "${result}" "ethereum import_privatekey"
# 在 chain33 上部署合约
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline create -f 1 -k "${chain33DeployKey}" -n "deploy crossx to chain33" -r "${chain33DeployAddr}, [${chain33Validatora}, ${chain33Validatorb}, ${chain33Validatorc}, ${chain33Validatord}], [25, 25, 25, 25]" --chainID "${chain33ID}"
result=$(${Boss4xCLI} chain33 offline send -f "deployCrossX2Chain33.txt")
for i in {0..7}; do
hash=$(echo "${result}" | jq -r ".[$i].TxHash")
check_tx "${Chain33Cli}" "${hash}"
done
BridgeRegistryOnChain33=$(echo "${result}" | jq -r ".[6].ContractAddr")
# shellcheck disable=SC2034
multisignChain33Addr=$(echo "${result}" | jq -r ".[7].ContractAddr")
${CLIA} chain33 multisign set_multiSign -a "${multisignChain33Addr}"
# 拷贝 BridgeRegistry.abi 和 BridgeBank.abi
cp BridgeRegistry.abi "${BridgeRegistryOnChain33}.abi"
chain33BridgeBank=$(${Chain33Cli} evm query -c "${chain33DeployAddr}" -b "bridgeBank()" -a "${BridgeRegistryOnChain33}")
cp Chain33BridgeBank.abi "${chain33BridgeBank}.abi"
# 在 Eth 上部署合约
# shellcheck disable=SC2154
${Boss4xCLI} ethereum offline create -p "25,25,25,25" -o "${ethDeployAddr}" -v "${ethValidatorAddra},${ethValidatorAddrb},${ethValidatorAddrc},${ethValidatorAddrd}"
${Boss4xCLI} ethereum offline sign -k "${ethDeployKey}"
result=$(${Boss4xCLI} ethereum offline send -f "deploysigntxs.txt")
for i in {0..7}; do
hash=$(echo "${result}" | jq -r ".[$i].TxHash")
check_eth_tx "${hash}"
done
BridgeRegistryOnEth=$(echo "${result}" | jq -r ".[6].ContractAddr")
ethBridgeBank=$(echo "${result}" | jq -r ".[3].ContractAddr")
# shellcheck disable=SC2034
multisignEthAddr=$(echo "${result}" | jq -r ".[7].ContractAddr")
${CLIA} ethereum multisign set_multiSign -a "${multisignEthAddr}"
# 拷贝 BridgeRegistry.abi 和 BridgeBank.abi
cp BridgeRegistry.abi "${BridgeRegistryOnEth}.abi"
cp EthBridgeBank.abi "${ethBridgeBank}.abi"
# 修改 relayer.toml 字段
updata_relayer "BridgeRegistryOnChain33" "${BridgeRegistryOnChain33}" "./relayer.toml"
line=$(delete_line_show "./relayer.toml" "BridgeRegistry=")
if [ "${line}" ]; then
sed -i ''"${line}"' a BridgeRegistry="'"${BridgeRegistryOnEth}"'"' "./relayer.toml"
fi
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function offline_deploy_erc20_eth_BYC() {
# eth 上 铸币 YCC
echo -e "${GRE}======= 在 ethereum 上创建 ERC20 BYC ======${NOC}"
# shellcheck disable=SC2154
${Boss4xCLI} ethereum offline create_erc20 -m 33000000000000000000 -s BYC -o "${ethTestAddr1}" -d "${ethDeployAddr}"
${Boss4xCLI} ethereum offline sign -f "deployErc20BYC.txt" -k "${ethDeployKey}"
sleep 10
result=$(${Boss4xCLI} ethereum offline send -f "deploysigntxs.txt")
hash=$(echo "${result}" | jq -r ".[0].TxHash")
check_eth_tx "${hash}"
ethereumBycERC20TokenAddr=$(echo "${result}" | jq -r ".[0].ContractAddr")
${Boss4xCLI} ethereum offline create_add_lock_list -s BYC -t "${ethereumBycERC20TokenAddr}" -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "create_add_lock_list.txt"
}
function offline_create_bridge_token_chain33_BYC() {
# 在chain33上创建bridgeToken YCC
echo -e "${GRE}======= 在 chain33 上创建 bridgeToken BYC ======${NOC}"
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline create_bridge_token -c "${chain33BridgeBank}" -s BYC -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "create_bridge_token.txt"
chain33BycBridgeTokenAddr=$(${Chain33Cli} evm query -a "${chain33BridgeBank}" -c "${chain33DeployAddr}" -b "getToken2address(BYC)")
echo "BYC Bridge Token Addr = ${chain33BycBridgeTokenAddr}"
cp BridgeToken.abi "${chain33BycBridgeTokenAddr}.abi"
result=$(${Chain33Cli} evm query -a "${chain33BycBridgeTokenAddr}" -c "${chain33BycBridgeTokenAddr}" -b "symbol()")
is_equal "${result}" "BYC"
${CLIA} chain33 token set -t "${chain33BycBridgeTokenAddr}" -s BYC
}
function offline_deploy_erc20_chain33_YCC() {
# chain33 token create YCC
echo -e "${GRE}======= 在 chain33 上创建 ERC20 YCC ======${NOC}"
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline create_erc20 -s YCC -k "${chain33DeployKey}" -o "${chain33TestAddr1}" --chainID "${chain33ID}"
result=$(${Boss4xCLI} chain33 offline send -f "deployErc20YCCChain33.txt")
hash=$(echo "${result}" | jq -r ".[0].TxHash")
check_tx "${Chain33Cli}" "${hash}"
chain33YccERC20TokenAddr=$(echo "${result}" | jq -r ".[0].ContractAddr")
cp ERC20.abi "${chain33YccERC20TokenAddr}.abi"
# echo 'YCC.1:增加allowance的设置,或者使用relayer工具进行'
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline approve_erc20 -a 330000000000 -s "${chain33BridgeBank}" -c "${chain33YccERC20TokenAddr}" -k "${chain33TestAddrKey1}" --chainID "${chain33ID}"
chain33_offline_send "approve_erc20.txt"
# echo 'YCC.2:#执行add lock操作:addToken2LockList'
${Boss4xCLI} chain33 offline create_add_lock_list -c "${chain33BridgeBank}" -s YCC -t "${chain33YccERC20TokenAddr}" -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "create_add_lock_list.txt"
}
function offline_deploy_erc20_chain33_ZBC() {
# chain33 token create ZBC
echo -e "${GRE}======= 在 chain33 上创建 ERC20 ZBC ======${NOC}"
${Boss4xCLI} chain33 offline create_erc20 -s ZBC -k "${chain33DeployKey}" -o "${chain33TestAddr1}" --chainID "${chain33ID}"
result=$(${Boss4xCLI} chain33 offline send -f "deployErc20ZBCChain33.txt")
hash=$(echo "${result}" | jq -r ".[0].TxHash")
check_tx "${Chain33Cli}" "${hash}"
chain33ZbcERC20TokenAddr=$(echo "${result}" | jq -r ".[0].ContractAddr")
cp ERC20.abi "${chain33ZbcERC20TokenAddr}.abi"
# echo 'ZBC.1:增加allowance的设置,或者使用relayer工具进行'
${Boss4xCLI} chain33 offline approve_erc20 -a 330000000000 -s "${chain33BridgeBank}" -c "${chain33ZbcERC20TokenAddr}" -k "${chain33TestAddrKey1}" --chainID "${chain33ID}"
chain33_offline_send "approve_erc20.txt"
# echo 'ZBC.2:#执行add lock操作:addToken2LockList'
${Boss4xCLI} chain33 offline create_add_lock_list -c "${chain33BridgeBank}" -s ZBC -t "${chain33ZbcERC20TokenAddr}" -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "create_add_lock_list.txt"
}
function offline_create_bridge_token_eth_BTY() {
# 在 Ethereum 上创建 bridgeToken BTY
echo -e "${GRE}======= 在 Ethereum 上创建 bridgeToken BTY ======${NOC}"
${Boss4xCLI} ethereum offline create_bridge_token -s BTY -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "create_bridge_token.txt"
ethereumBtyBridgeTokenAddr=$(${CLIA} ethereum receipt -s "${hash}" | jq -r .logs[0].address)
${CLIA} ethereum token set -t "${ethereumBtyBridgeTokenAddr}" -s BTY
}
function offline_create_bridge_token_chain33_ETH() {
# 在 chain33 上创建 bridgeToken ETH
echo -e "${GRE}======= 在 chain33 上创建 bridgeToken ETH ======${NOC}"
${Boss4xCLI} chain33 offline create_bridge_token -c "${chain33BridgeBank}" -s ETH -k "${chain33DeployKey}" --chainID "${chain33ID}" -n "create_bridge_token:ETH"
chain33_offline_send "create_bridge_token.txt"
chain33EthBridgeTokenAddr=$(${Chain33Cli} evm query -a "${chain33BridgeBank}" -c "${chain33DeployAddr}" -b "getToken2address(ETH)")
echo "ETH Token Addr= ${chain33EthBridgeTokenAddr}"
cp BridgeToken.abi "${chain33EthBridgeTokenAddr}.abi"
result=$(${Chain33Cli} evm query -a "${chain33EthBridgeTokenAddr}" -c "${chain33EthBridgeTokenAddr}" -b "symbol()")
is_equal "${result}" "ETH"
${CLIA} chain33 token set -t "${chain33EthBridgeTokenAddr}" -s ETH
}
function offline_create_bridge_token_eth_YCC() {
# ethereum create-bridge-token YCC
echo -e "${GRE}======= 在 ethereum 上创建 bridgeToken ycc ======${NOC}"
${Boss4xCLI} ethereum offline create_bridge_token -s YCC -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "create_bridge_token.txt"
ethereumYccBridgeTokenAddr=$(${CLIA} ethereum receipt -s "${hash}" | jq -r .logs[0].address)
${CLIA} ethereum token set -t "${ethereumYccBridgeTokenAddr}" -s YCC
cp BridgeToken.abi "${ethereumYccBridgeTokenAddr}.abi"
}
function offline_create_bridge_token_eth_ZBC() {
# ethereum create-bridge-token ZBC
echo -e "${GRE}======= 在 ethereum 上创建 bridgeToken ZBC ======${NOC}"
${Boss4xCLI} ethereum offline create_bridge_token -s ZBC -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "create_bridge_token.txt"
ethereumZbcBridgeTokenAddr=$(${CLIA} ethereum receipt -s "${hash}" | jq -r .logs[0].address)
${CLIA} ethereum token set -t "${ethereumZbcBridgeTokenAddr}" -s ZBC
cp BridgeToken.abi "${ethereumZbcBridgeTokenAddr}.abi"
}
function offline_setupChain33Multisign() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== 设置 chain33 离线钱包合约 ===========${NOC}"
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline multisign_setup -m "${multisignChain33Addr}" -o "${chain33MultisignA},${chain33MultisignB},${chain33MultisignC},${chain33MultisignD}" -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "multisign_setup.txt"
${Boss4xCLI} chain33 offline set_offline_addr -a "${multisignChain33Addr}" -c "${chain33BridgeBank}" -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "chain33_set_offline_addr.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function offline_setupEthMultisign() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== 设置 ETH 离线钱包合约 ===========${NOC}"
# shellcheck disable=SC2154
${Boss4xCLI} ethereum offline multisign_setup -m "${multisignEthAddr}" -d "${ethDeployAddr}" -o "${ethMultisignA},${ethMultisignB},${ethMultisignC},${ethMultisignD}"
ethereum_offline_sign_send "multisign_setup.txt"
${Boss4xCLI} ethereum offline set_offline_addr -a "${multisignEthAddr}" -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "set_offline_addr.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function offline_transfer_multisign_Eth_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# transfer
# shellcheck disable=SC2154
# ${CLIA} ethereum multisign transfer -a 3 -r "${ethBridgeBank}" -o "${ethValidatorAddrKeyB}" -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
${Boss4xCLI} ethereum offline multisign_transfer_prepare -a 3 -r "${ethBridgeBank}" -c "${multisignEthAddr}" -d "${ethTestAddr1}"
# shellcheck disable=SC2154
${Boss4xCLI} ethereum offline sign_multisign_tx -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
${Boss4xCLI} ethereum offline create_multisign_tx
# shellcheck disable=SC2154
ethereum_offline_sign_send create_multisign_tx.txt "${ethTestAddrKey1}"
sleep 10
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
cli_ret "${result}" "balance" ".balance" "16"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}")
cli_ret "${result}" "balance" ".balance" "20"
# transfer
# shellcheck disable=SC2154
# ${CLIA} ethereum multisign transfer -a 5 -r "${ethMultisignA}" -o "${ethValidatorAddrKeyB}" -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
${Boss4xCLI} ethereum offline multisign_transfer_prepare -a 5 -r "${ethMultisignA}" -c "${multisignEthAddr}" -d "${ethTestAddr1}"
${Boss4xCLI} ethereum offline sign_multisign_tx -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
${Boss4xCLI} ethereum offline create_multisign_tx
ethereum_offline_sign_send create_multisign_tx.txt "${ethTestAddrKey1}"
sleep 10
result=$(${CLIA} ethereum balance -o "${ethMultisignA}")
cli_ret "${result}" "balance" ".balance" "1005"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}")
cli_ret "${result}" "balance" ".balance" "15"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function offline_transfer_multisign_EthYcc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# transfer
${Boss4xCLI} ethereum offline multisign_transfer_prepare -a 8 -r "${ethBridgeBank}" -c "${multisignEthAddr}" -d "${ethTestAddr1}" -t "${ethereumBycERC20TokenAddr}"
${Boss4xCLI} ethereum offline sign_multisign_tx -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
${Boss4xCLI} ethereum offline create_multisign_tx
ethereum_offline_sign_send create_multisign_tx.txt "${ethTestAddrKey1}"
sleep 10
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "80"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "80"
# transfer
# ${CLIA} ethereum multisign transfer -a 10 -r "${ethMultisignA}" -o "${ethValidatorAddrKeyB}" -t "${ethereumBycERC20TokenAddr}" -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
${Boss4xCLI} ethereum offline multisign_transfer_prepare -a 10 -r "${ethMultisignA}" -c "${multisignEthAddr}" -d "${ethTestAddr1}" -t "${ethereumBycERC20TokenAddr}"
${Boss4xCLI} ethereum offline sign_multisign_tx -k "${ethMultisignKeyA},${ethMultisignKeyB},${ethMultisignKeyC},${ethMultisignKeyD}"
${Boss4xCLI} ethereum offline create_multisign_tx
ethereum_offline_sign_send create_multisign_tx.txt "${ethTestAddrKey1}"
sleep 10
result=$(${CLIA} ethereum balance -o "${ethMultisignA}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "10"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "70"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function offline_transfer_multisign_Chain33Ycc_test() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# transfer test
# hash=$(${CLIA} chain33 multisign transfer -a 10 -r "${chain33BridgeBank}" -t "${chain33YccERC20TokenAddr}" -k "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" | jq -r ".msg")
${Boss4xCLI} chain33 offline create_multisign_transfer -a 10 -r "${chain33BridgeBank}" -m "${multisignChain33Addr}" -t "${chain33YccERC20TokenAddr}"
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline multisign_transfer -k "${chain33DeployKey}" -s "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" --chainID "${chain33ID}"
chain33_offline_send "multisign_transfer.txt"
sleep 10
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${chain33BridgeBank}" -b "balanceOf(${chain33BridgeBank})")
is_equal "${result}" "6200000000"
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${multisignChain33Addr}" -b "balanceOf(${multisignChain33Addr})")
is_equal "${result}" "30800000000"
# hash=$(${CLIA} chain33 multisign transfer -a 5 -r "${chain33MultisignA}" -t "${chain33YccERC20TokenAddr}" -k "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" | jq -r ".msg")
${Boss4xCLI} chain33 offline create_multisign_transfer -a 5 -r "${chain33MultisignA}" -m "${multisignChain33Addr}" -t "${chain33YccERC20TokenAddr}"
# shellcheck disable=SC2154
${Boss4xCLI} chain33 offline multisign_transfer -k "${chain33DeployKey}" -s "${chain33MultisignKeyA},${chain33MultisignKeyB},${chain33MultisignKeyC},${chain33MultisignKeyD}" --chainID "${chain33ID}"
chain33_offline_send "multisign_transfer.txt"
sleep 10
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${chain33MultisignA}" -b "balanceOf(${chain33MultisignA})")
is_equal "${result}" "500000000"
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${multisignChain33Addr}" -b "balanceOf(${multisignChain33Addr})")
is_equal "${result}" "30300000000"
# 判断 ETH 这端是否金额一致
result=$(${CLIA} ethereum balance -o "${ethTestAddr1}" -t "${ethereumYccBridgeTokenAddr}")
cli_ret "${result}" "balance" ".balance" "370"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
# shellcheck disable=SC2155
set -x
set -e
# 公用测试函数
#color
RED='\033[1;31m'
GRE='\033[1;32m'
NOC='\033[0m'
# 出错退出前拷贝日志文件
function exit_cp_file() {
exit 1
set -x
# shellcheck disable=SC2116
dirNameFa=$(echo ~)
dirName="${dirNameFa}/x2ethereumlogs"
if [ ! -d "${dirName}" ]; then
# shellcheck disable=SC2086
mkdir -p ${dirName}
fi
for name in a b c d; do
# shellcheck disable=SC2154
docker cp "${dockerNamePrefix}_ebrelayer${name}_1":/root/logs/x2Ethereum_relayer.log "${dirName}/ebrelayer${name}.log"
docker exec "${dockerNamePrefix}_ebrelayer${name}_1" tail -n 1000 /root/logs/x2Ethereum_relayer.log
done
docker cp "${dockerNamePrefix}_chain33_1":/root/logs/chain33.log "${dirName}/chain33.log"
docker logs "${dockerNamePrefix}_chain33_1" | tail -n 1000
exit 1
}
function copyErrLogs() {
set -x
if [ -n "$CASE_ERR" ]; then
# /var/lib/jenkins
# shellcheck disable=SC2116
dirNameFa=$(echo ~)
dirName="${dirNameFa}/x2ethereumlogs"
if [ ! -d "${dirName}" ]; then
# shellcheck disable=SC2086
mkdir -p ${dirName}
fi
for name in a b c d; do
# shellcheck disable=SC2154
docker cp "${dockerNamePrefix}_ebrelayer${name}_rpc_1":/root/logs/x2Ethereum_relayer.log "${dirName}/ebrelayer${name}_rpc.log"
docker exec "${dockerNamePrefix}_ebrelayer${name}_rpc_1" tail -n 1000 /root/logs/x2Ethereum_relayer.log
done
docker cp "${dockerNamePrefix}_chain33_1":/root/logs/chain33.log "${dirName}/chain33_rpc.log"
docker logs "${dockerNamePrefix}_chain33_1" | tail -n 1000
fi
}
# 判断结果是否正确
function cli_ret() {
set +x
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong parameter${NOC}"
exit_cp_file
fi
ok=$(echo "${1}" | jq -r .isOK)
if [[ ${ok} != "true" ]]; then
echo -e "${RED}failed to ${2}${NOC}"
exit_cp_file
fi
local jqMsg=".msg"
if [[ $# -ge 3 ]]; then
jqMsg="${3}"
fi
msg=$(echo "${1}" | jq -r "${jqMsg}")
if [[ $# -eq 4 ]]; then
if [ "$(echo "$msg < $4" | bc)" -eq 1 ] || [ "$(echo "$msg > $4" | bc)" -eq 1 ]; then
echo -e "${RED}The balance is not correct${NOC}"
exit_cp_file
fi
fi
set -x
echo "${msg}"
}
# 判断 chain33 金额是否正确
function balance_ret() {
set +x
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong parameter${NOC}"
exit_cp_file
fi
local balance=$(echo "${1}" | jq -r ".balance")
if [ "$(echo "$balance < $2" | bc)" -eq 1 ] || [ "$(echo "$balance > $2" | bc)" -eq 1 ]; then
echo -e "${RED}The balance is not correct${NOC}"
exit_cp_file
fi
set -x
echo "${balance}"
}
# 查询关键字所在行然后删除 ${1}文件名称 ${2}关键字
function delete_line() {
line=$(cat -n "${1}" | grep "${2}" | awk '{print $1}' | xargs | awk '{print $1}')
if [ "${line}" ]; then
sed -i "${line}"'d' "${1}" # 删除行
fi
}
# 查询关键字所在行然后删除 ${1}文件名称 ${2}关键字
function delete_line_show() {
local line=$(cat -n "${1}" | grep "${2}" | awk '{print $1}' | xargs | awk '{print $1}')
if [ "${line}" ]; then
sed -i "${line}"'d' "${1}" # 删除行
line=$((line - 1))
fi
echo "${line}"
}
# 后台启动 ebrelayer 进程 $1 docker 名称 $2进程名称 $3进程信息输出重定向文件
function start_docker_ebrelayer() {
# 参数如果小于 3 直接报错
if [[ $# -lt 3 ]]; then
echo -e "${RED}wrong parameter${NOC}"
exit_cp_file
fi
# 后台启动程序
docker exec "$1" nohup "${2}" >"${3}" 2>&1 &
sleep 2
# shellcheck disable=SC2009
pid=$(docker exec "$1" ps -ef | grep "$2" | grep -v 'grep' | awk '{print $2}' | xargs)
local count=0
while [ "${pid}" == "" ]; do
docker exec "$1" nohup "${2}" >"${3}" 2>&1 &
sleep 2
count=$((count + 1))
if [[ ${count} -ge 20 ]]; then
echo -e "${RED}start ${1} ${2} failed${NOC}"
exit_cp_file
fi
# shellcheck disable=SC2009
pid=$(docker exec "$1" ps -ef | grep "$2" | grep -v 'grep' | awk '{print $2}' | xargs)
done
}
# 后台启动 ebrelayer 进程 $1进程名称 $2进程信息输出重定向文件
function start_ebrelayer() {
# 参数如果小于 2 直接报错
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong parameter${NOC}"
exit_cp_file
fi
# 判断可执行文件是否存在
if [ ! -x "${1}" ]; then
echo -e "${RED}${1} not exist${NOC}"
exit_cp_file
fi
# 后台启动程序
nohup "${1}" >"${2}" 2>&1 &
sleep 2
# shellcheck disable=SC2009
pid=$(ps -ef | grep "${1}" | grep -v 'grep' | awk '{print $2}' | xargs)
local count=0
while [ "${pid}" == "" ]; do
nohup "${1}" >"${2}" 2>&1 &
sleep 2
count=$((count + 1))
if [[ ${count} -ge 20 ]]; then
echo -e "${RED}start ${1} failed${NOC}"
exit_cp_file
fi
# shellcheck disable=SC2009
pid=$(ps -ef | grep "${1}" | grep -v 'grep' | awk '{print $2}' | xargs)
done
}
# 后台启动 ebrelayer 进程 $1 A B C D
function start_ebrelayer_and_unlock() {
start_ebrelayer "./${1}/ebrelayer" "./${1}/ebrelayer.log"
sleep 2
local CLI="./ebcli_$1"
local count=0
while true; do
result=$(${CLI} relayer unlock -p 123456hzj | jq -r .isOK)
if [[ ${result} == "true" ]]; then
break
fi
count=$((count + 1))
if [[ ${count} == 5 ]]; then
echo -e "${RED}failed to unlock${NOC}"
exit_cp_file
fi
sleep 1
done
}
# 后台启动 ebrelayer 进程 $1 A B C D
function start_ebrelayer_and_setpwd_unlock() {
start_ebrelayer "./${1}/ebrelayer" "./${1}/ebrelayer.log"
sleep 2
local CLI="./ebcli_$1"
local count=0
while true; do
result=$(${CLI} relayer set_pwd -p 123456hzj | jq -r .isOK)
if [[ ${result} == "true" ]]; then
break
fi
count=$((count + 1))
if [[ ${count} == 5 ]]; then
echo -e "${RED}failed to set_pwd${NOC}"
exit_cp_file
fi
sleep 1
done
count=0
while true; do
result=$(${CLI} relayer unlock -p 123456hzj | jq -r .isOK)
if [[ ${result} == "true" ]]; then
break
fi
count=$((count + 1))
if [[ ${count} == 5 ]]; then
echo -e "${RED}failed to unlock${NOC}"
exit_cp_file
fi
sleep 1
done
}
# 杀死进程 ebrelayer 进程 docker ebrelayer 名称
function kill_docker_ebrelayer() {
# shellcheck disable=SC2009
pid=$(docker exec "$1" ps -ef | grep "ebrelayer" | grep -v 'grep' | awk '{print $2}' | xargs)
if [ "${pid}" == "" ]; then
echo "not find ${1} pid"
return
fi
docker exec "$1" kill "${pid}"
# shellcheck disable=SC2009
pid=$(docker exec "$1" ps -ef | grep "ebrelayer" | grep -v 'grep' | awk '{print $2}' | xargs)
if [ "${pid}" != "" ]; then
echo "kill ${1} failed"
docker exec "$1" kill -9 "${pid}"
fi
sleep 1
}
# 杀死进程ebrelayer 进程 $1进程名称
function kill_ebrelayer() {
# shellcheck disable=SC2009
ps -ef | grep "${1}"
# shellcheck disable=SC2009
pid=$(ps -ef | grep "${1}" | grep -v 'grep' | awk '{print $2}' | xargs)
if [ "${pid}" == "" ]; then
echo "not find ${1} pid"
return
fi
kill -9 "${pid}"
sleep 1
# shellcheck disable=SC2009
pid=$(ps -ef | grep "${1}" | grep -v 'grep' | awk '{print $2}' | xargs)
if [ "${pid}" != "" ]; then
echo "kill ${1} failed"
kill -9 "${pid}"
fi
sleep 1
}
# chain33 区块等待 $1:cli 路径 $2:等待高度
function block_wait() {
set +x
local CLI=${1}
if [[ $# -lt 1 ]]; then
echo -e "${RED}wrong block_wait parameter${NOC}"
exit_cp_file
fi
local cur_height=$(${CLI} block last_header | jq ".height")
local expect=$((cur_height + ${2}))
local count=0
while true; do
new_height=$(${CLI} block last_header | jq ".height")
if [[ ${new_height} -ge ${expect} ]]; then
break
fi
count=$((count + 1))
sleep 1
done
count=$((count + 1))
set -x
echo -e "${GRE}chain33 wait new block $count s, cur height=$expect,old=$cur_height${NOC}"
}
# 检查交易是否执行成功 $1:cli 路径 $2:交易hash
function check_tx() {
set +x
local CLI=${1}
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong check_tx parameters${NOC}"
exit_cp_file
fi
if [[ ${2} == "" ]]; then
echo -e "${RED}wrong check_tx txHash is empty${NOC}"
exit_cp_file
fi
local count=0
while true; do
ty=$(${CLI} tx query -s "${2}" | jq .receipt.ty)
if [[ ${ty} != "" ]]; then
break
fi
count=$((count + 1))
sleep 1
if [[ ${count} -ge 100 ]]; then
echo "chain33 query tx for too long"
break
fi
done
set -x
ty=$(${CLI} tx query -s "${2}" | jq .receipt.ty)
if [[ ${ty} != 2 ]]; then
echo -e "${RED}check tx error, hash is ${2}${NOC}"
exit_cp_file
fi
}
function check_number() {
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong check number parameters${NOC}"
exit_cp_file
fi
if [ "$(echo "$1 < $2" | bc)" -eq 1 ] || [ "$(echo "$1 > $2" | bc)" -eq 1 ]; then
echo -e "${RED}error number, expect ${1}, get ${2}${NOC}"
exit_cp_file
fi
}
# 检查地址是否匹配 $1返回结果 $2匹配地址
function check_addr() {
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong check number parameters${NOC}"
exit_cp_file
fi
addr=$(echo "${1}" | jq -r ".acc.addr")
if [[ ${addr} != "${2}" ]]; then
echo -e "${RED}error addr, expect ${1}, get ${2}${NOC}"
exit_cp_file
fi
}
# $1 dockerName
function get_docker_addr() {
local dockerAddr=$(docker inspect "${1}" | jq ".[].NetworkSettings.Networks" | grep "IPAddress" | awk '{ print $2}' | sed 's/\"//g' | sed 's/,//g')
echo "${dockerAddr}"
}
# $1 dockerAddr; $2 docker ebrelayer name; $3 relayer.toml 地址
function updata_relayer_a_toml() {
local dockerAddr=${1}
local ebrelayer=${2}
local file=${3}
# shellcheck disable=SC2155
local line=$(delete_line_show "${file}" 'EthProvider="ws:')
sed -i ''"${line}"' a EthProvider="ws://'"${dockerAddr}"':8545/"' "${file}"
line=$(delete_line_show "${file}" 'EthProviderCli="http:')
sed -i ''"${line}"' a EthProviderCli="http://'"${dockerAddr}"':8545"' "${file}"
pushHost=$(get_docker_addr "${ebrelayer}")
line=$(delete_line_show "${file}" "pushHost")
sed -i ''"${line}"' a pushHost="http://'"${pushHost}"':20000"' "${file}"
line=$(delete_line_show "${file}" "pushBind")
sed -i ''"${line}"' a pushBind="'"${pushHost}"':20000"' "${file}"
local chain33Host=$(get_docker_addr "${dockerNamePrefix}_chain33_1")
if [[ ${chain33Host} == "" ]]; then
echo -e "${RED}chain33Host is empty${NOC}"
exit_cp_file
fi
local line=$(delete_line_show "${file}" "chain33Host")
# 在第 line 行后面 新增合约地址
sed -i ''"${line}"' a chain33Host="http://'"${chain33Host}"':8801"' "${file}"
sed -i 's/^EthBlockFetchPeriod=.*/EthBlockFetchPeriod=500/g' "${file}"
sed -i 's/^fetchHeightPeriodMs=.*/fetchHeightPeriodMs=500/g' "${file}"
}
# 更新配置文件 $1 为 BridgeRegistry 合约地址; $2 等待区块 默认10; $3 relayer.toml 地址
function updata_relayer_toml() {
local BridgeRegistry=${1}
local maturityDegree=${2}
local file=${3}
line=$(delete_line_show "${file}" "BridgeRegistry")
sed -i ''"${line}"' a BridgeRegistry="'"${BridgeRegistry}"'"' "${file}"
sed -i 's/EthMaturityDegree=10/'EthMaturityDegree="${maturityDegree}"'/g' "${file}"
sed -i 's/maturityDegree=10/'maturityDegree="${maturityDegree}"'/g' "${file}"
}
# 更新配置文件 $1 为 BridgeRegistry 合约地址; $2 等待区块 默认10; $3 relayer.toml 地址
function updata_relayer_toml_ropston() {
local BridgeRegistry=${1}
local maturityDegree=${2}
local file=${3}
local chain33Host=127.0.0.1
local pushHost=127.0.0.1
local line=$(delete_line_show "${file}" "chain33Host")
# 在第 line 行后面 新增合约地址
sed -i ''"${line}"' a chain33Host="http://'${chain33Host}':8801"' "${file}"
line=$(delete_line_show "${file}" "pushHost")
sed -i ''"${line}"' a pushHost="http://'${pushHost}':20000"' "${file}"
line=$(delete_line_show "${file}" "BridgeRegistry")
sed -i ''"${line}"' a BridgeRegistry="'"${BridgeRegistry}"'"' "${file}"
sed -i 's/EthMaturityDegree=10/'EthMaturityDegree="${maturityDegree}"'/g' "${file}"
sed -i 's/maturityDegree=10/'maturityDegree="${maturityDegree}"'/g' "${file}"
}
# 获取本机 IP
function get_inet_addr() {
inetAddr=$(ifconfig wlp2s0 | grep "inet " | awk '{ print $2}' | awk -F: '{print $2}')
if [[ ${inetAddr} == "" ]]; then
inetAddr=$(ifconfig wlp2s0 | grep "inet " | awk '{ print $2}')
if [[ ${inetAddr} == "" ]]; then
inetAddr=$(ifconfig eth0 | grep "inet " | awk '{ print $2}' | awk -F: '{print $2}')
if [[ ${inetAddr} == "" ]]; then
inetAddr=$(ifconfig eth0 | grep "inet " | awk '{ print $2}')
if [[ ${inetAddr} == "" ]]; then
ip addr show eth0
inetAddr=$(ip addr show eth0 | grep "inet " | awk '{ print $2}' | head -c-4)
fi
fi
fi
fi
echo "${inetAddr}"
}
# 启动 eth
function start_trufflesuite() {
# 如果原来存在先删除
local ganacheName=ganachetest
local isExit=$(docker inspect ${ganacheName} | jq ".[]" | jq ".Id")
if [[ ${isExit} != "" ]]; then
docker stop ${ganacheName}
docker rm ${ganacheName}
fi
# 启动 eth
docker run -d -e 10000 --name ${ganacheName} -p 7545:8545 -l eth_test trufflesuite/ganache-cli:latest -a 20 --debug -b 1 -m "coast bar giraffe art venue decide symbol law visual crater vital fold" -l 0x7a1200
sleep 1
}
# eth 区块等待 $1:等待高度 $2:url地址,默认为 http://localhost:7545,测试网络用 https://ropsten-rpc.linkpool.io/
function eth_block_wait() {
set +x
if [[ $# -lt 0 ]]; then
echo -e "${RED}wrong block_wait parameter${NOC}"
exit_cp_file
fi
local cur_height=""
local new_height=""
local url=${2}
if [ "${url}" == "" ]; then
cur_height=$(curl -ksd '{"id":1,"jsonrpc":"2.0","method":"eth_blockNumber","params":[]}' http://localhost:7545 | jq -r ".result")
else
cur_height=$(curl -H "Content-Type: application/json" -X POST --data '{"id":1,"jsonrpc":"2.0","method":"eth_blockNumber","params":[]}' "${url}" | jq -r ".result")
fi
local expect=$((cur_height + ${1} + 1))
local count=0
while true; do
if [ "${url}" == "" ]; then
new_height=$(curl -ksd '{"id":1,"jsonrpc":"2.0","method":"eth_blockNumber","params":[]}' http://localhost:7545 | jq -r ".result")
else
new_height=$(curl -H "Content-Type: application/json" -X POST --data '{"id":1,"jsonrpc":"2.0","method":"eth_blockNumber","params":[]}' "${url}" | jq -r ".result")
fi
if [[ ${new_height} -ge ${expect} ]]; then
break
fi
count=$((count + 1))
sleep 1
done
count=$((count + 1))
sleep 1
set -x
echo -e "${GRE}eth wait new block $count s, cur height=$expect,old=$((cur_height))${NOC}"
}
# $1 fileName 例如:./relayer.toml
function pushNameChange() {
local file=${1}
# 修改 relayer.toml 配置文件 pushName 字段
line=$(delete_line_show "${file}" "pushName")
local time=$(date "+%m-%d-%H:%M:%S")
sed -i ''"${line}"' a pushName="cross2eth_'"${time}"'"' "${file}"
}
# $1 keyName $2 newData $3 file
function updata_relayer() {
local keyName=${1}
local newData=${2}
local file=${3}
line=$(delete_line_show "${file}" "${keyName}")
sed -i ''"${line}"' a '"${keyName}"'="'"${newData}"'"' "${file}"
}
# 判断结果 $1 和 $2 是否相等
function is_equal() {
set +x
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong parameter${NOC}"
exit_cp_file
fi
if [[ $1 != "$2" ]]; then
echo -e "${RED}$1 != ${2}${NOC}"
exit_cp_file
fi
set -x
}
function kill_all_ebrelayer() {
kill_ebrelayer ebrelayer
sleep 2
rm datadir/ logs/ -rf
for name in B C D; do
kill_ebrelayer relayer_${name}/ebrelayer
sleep 2
rm relayer_${name} -rf
mkdir relayer_${name}
cp ./ebrelayer relayer_${name}/ebrelayer
done
}
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
set -x
set +e
source "./publicTest.sh"
# shellcheck disable=SC2034
{
chain33MultisignA="168Sn1DXnLrZHTcAM9stD6t2P49fNuJfJ9"
chain33MultisignB="13KTf57aCkVVJYNJBXBBveiA5V811SrLcT"
chain33MultisignC="1JQwQWsShTHC4zxHzbUfYQK4kRBriUQdEe"
chain33MultisignD="1NHuKqoKe3hyv52PF8XBAyaTmJWAqA2Jbb"
chain33MultisignKeyA="0xcd284cd17456b73619fa609bb9e3105e8eff5d059c5e0b6eb1effbebd4d64144"
chain33MultisignKeyB="0xe892212221b3b58211b90194365f4662764b6d5474ef2961ef77c909e31eeed3"
chain33MultisignKeyC="0x9d19a2e9a440187010634f4f08ce36e2bc7b521581436a99f05568be94dc66ea"
chain33MultisignKeyD="0x45d4ce009e25e6d5e00d8d3a50565944b2e3604aa473680a656b242d9acbff35"
ethMultisignA=0x4c85848a7E2985B76f06a7Ed338FCB3aF94a7DCf
ethMultisignB=0x6F163E6daf0090D897AD7016484f10e0cE844994
ethMultisignC=0xbc333839E37bc7fAAD0137aBaE2275030555101f
ethMultisignD=0x495953A743ef169EC5D4aC7b5F786BF2Bd56aFd5
ethMultisignKeyA=0x5e8aadb91eaa0fce4df0bcc8bd1af9e703a1d6db78e7a4ebffd6cf045e053574
ethMultisignKeyB=0x0504bcb22b21874b85b15f1bfae19ad62fc2ad89caefc5344dc669c57efa60db
ethMultisignKeyC=0x0c61f5a879d70807686e43eccc1f52987a15230ae0472902834af4d1933674f2
ethMultisignKeyD=0x2809477ede1261da21270096776ba7dc68b89c9df5f029965eaa5fe7f0b80697
}
maturityDegree=10
Chain33Cli="../../chain33-cli"
BridgeRegistryOnChain33=""
chain33BridgeBank=""
BridgeRegistryOnEth=""
ethBridgeBank=""
chain33BtyERC20TokenAddr="1111111111111111111114oLvT2"
#
chain33EthBridgeTokenAddr=""
ethereumBtyBridgeTokenAddr=""
# etheruem erc20 ycc
ethereumBycERC20TokenAddr=""
chain33BycBridgeTokenAddr=""
# chain33 erc20 ycc
chain33YccERC20TokenAddr=""
ethereumYccBridgeTokenAddr=""
CLIA="./ebcli_A"
# shellcheck disable=SC2034
CLIB="./ebcli_B"
CLIC="./ebcli_C"
CLID="./ebcli_D"
chain33ID=0
function kill_ebrelayerC() {
kill_ebrelayer ./relayer_C/ebrelayer
sleep 1
}
function kill_ebrelayerD() {
kill_ebrelayer ./relayer_D/ebrelayer
sleep 1
}
function start_ebrelayerC() {
nohup ./relayer_C/ebrelayer ./relayer_C/relayer.toml >./relayer_C/cross2eth_C.log 2>&1 &
sleep 2
${CLIC} unlock -p 123456hzj
${Chain33Cli} send coins transfer -a 1 -n note -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
${Chain33Cli} send coins transfer -a 1 -n note -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
sleep ${maturityDegree}
eth_block_wait 12
}
function start_ebrelayerD() {
nohup ./relayer_D/ebrelayer ./relayer_D/relayer.toml >./relayer_D/cross2eth_D.log 2>&1 &
sleep 2
${CLID} unlock -p 123456hzj
${Chain33Cli} send coins transfer -a 1 -n note -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
${Chain33Cli} send coins transfer -a 1 -n note -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
sleep ${maturityDegree}
eth_block_wait 12
}
function InitAndDeploy() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
result=$(${CLIA} set_pwd -p 123456hzj)
cli_ret "${result}" "set_pwd"
result=$(${CLIA} unlock -p 123456hzj)
cli_ret "${result}" "unlock"
# shellcheck disable=SC2154
result=$(${CLIA} chain33 import_privatekey -k "${chain33DeployKey}")
cli_ret "${result}" "chain33 import_privatekey"
# shellcheck disable=SC2154
result=$(${CLIA} ethereum import_privatekey -k "${ethDeployKey}")
cli_ret "${result}" "ethereum import_privatekey"
# 在 chain33 上部署合约
result=$(${CLIA} chain33 deploy)
cli_ret "${result}" "chain33 deploy"
BridgeRegistryOnChain33=$(echo "${result}" | jq -r ".msg")
# 拷贝 BridgeRegistry.abi 和 BridgeBank.abi
cp BridgeRegistry.abi "${BridgeRegistryOnChain33}.abi"
# shellcheck disable=SC2154
chain33BridgeBank=$(${Chain33Cli} evm query -c "${chain33DeployAddr}" -b "bridgeBank()" -a "${BridgeRegistryOnChain33}")
cp Chain33BridgeBank.abi "${chain33BridgeBank}.abi"
# 在 Eth 上部署合约
result=$(${CLIA} ethereum deploy)
cli_ret "${result}" "ethereum deploy"
BridgeRegistryOnEth=$(echo "${result}" | jq -r ".msg")
# 拷贝 BridgeRegistry.abi 和 BridgeBank.abi
cp BridgeRegistry.abi "${BridgeRegistryOnEth}.abi"
result=$(${CLIA} ethereum bridgeBankAddr)
ethBridgeBank=$(echo "${result}" | jq -r ".addr")
cp EthBridgeBank.abi "${ethBridgeBank}.abi"
# 修改 relayer.toml 字段
updata_relayer "BridgeRegistryOnChain33" "${BridgeRegistryOnChain33}" "./relayer.toml"
line=$(delete_line_show "./relayer.toml" "BridgeRegistry=")
if [ "${line}" ]; then
sed -i ''"${line}"' a BridgeRegistry="'"${BridgeRegistryOnEth}"'"' "./relayer.toml"
fi
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function create_bridge_token_eth_BTY() {
# 在 Ethereum 上创建 bridgeToken BTY
echo -e "${GRE}======= 在 Ethereum 上创建 bridgeToken BTY ======${NOC}"
result=$(${CLIA} ethereum token create-bridge-token -s BTY)
cli_ret "${result}" "ethereum token create-bridge-token -s BTY"
# shellcheck disable=SC2034
ethereumBtyBridgeTokenAddr=$(echo "${result}" | jq -r .addr)
}
function create_bridge_token_chain33_ETH() {
# 在 chain33 上创建 bridgeToken ETH
echo -e "${GRE}======= 在 chain33 上创建 bridgeToken ETH ======${NOC}"
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33BridgeBank}" -p "createNewBridgeToken(ETH)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
chain33EthBridgeTokenAddr=$(${Chain33Cli} evm query -a "${chain33BridgeBank}" -c "${chain33DeployAddr}" -b "getToken2address(ETH)")
echo "ETH Token Addr= ${chain33EthBridgeTokenAddr}"
cp BridgeToken.abi "${chain33EthBridgeTokenAddr}.abi"
result=$(${Chain33Cli} evm query -a "${chain33EthBridgeTokenAddr}" -c "${chain33EthBridgeTokenAddr}" -b "symbol()")
is_equal "${result}" "ETH"
}
function deploy_erc20_eth_BYC() {
# eth 上 铸币 YCC
echo -e "${GRE}======= 在 ethereum 上创建 ERC20 ycc ======${NOC}"
# shellcheck disable=SC2154
result=$(${CLIA} ethereum deploy_erc20 -c "${ethDeployAddr}" -n BYC -s BYC -m 33000000000000000000)
cli_ret "${result}" "ethereum deploy_erc20 -s BYC"
ethereumBycERC20TokenAddr=$(echo "${result}" | jq -r .msg)
result=$(${CLIA} ethereum token add_lock_list -s BYC -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "add_lock_list"
}
function create_bridge_token_chain33_YCC() {
# 在chain33上创建bridgeToken YCC
echo -e "${GRE}======= 在 chain33 上创建 bridgeToken YCC ======${NOC}"
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33BridgeBank}" -p "createNewBridgeToken(YCC)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
chain33BycBridgeTokenAddr=$(${Chain33Cli} evm query -a "${chain33BridgeBank}" -c "${chain33DeployAddr}" -b "getToken2address(YCC)")
echo "YCC Token Addr = ${chain33BycBridgeTokenAddr}"
cp BridgeToken.abi "${chain33BycBridgeTokenAddr}.abi"
result=$(${Chain33Cli} evm query -a "${chain33BycBridgeTokenAddr}" -c "${chain33BycBridgeTokenAddr}" -b "symbol()")
is_equal "${result}" "YCC"
}
function deploy_erc20_chain33_YCC() {
# chain33 token create YCC
echo -e "${GRE}======= 在 chain33 上创建 ERC20 YCC ======${NOC}"
result=$(${CLIA} chain33 token create -s YCC -o "${chain33DeployAddr}")
cli_ret "${result}" "chain33 token create -s YCC"
chain33YccERC20TokenAddr=$(echo "${result}" | jq -r .msg)
cp ERC20.abi "${chain33YccERC20TokenAddr}.abi"
# echo 'YCC.1:增加allowance的设置,或者使用relayer工具进行'
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33YccERC20TokenAddr}" -p "approve(${chain33BridgeBank}, 330000000000)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
# echo 'YCC.2:#执行add lock操作:addToken2LockList'
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33BridgeBank}" -p "addToken2LockList(${chain33YccERC20TokenAddr}, YCC)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
}
function create_bridge_token_eth_YCC() {
# ethereum create-bridge-token YCC
echo -e "${GRE}======= 在 ethereum 上创建 bridgeToken ycc ======${NOC}"
result=$(${CLIA} ethereum token create-bridge-token -s YCC)
cli_ret "${result}" "ethereum token create -s YCC"
ethereumYccBridgeTokenAddr=$(echo "${result}" | jq -r .addr)
cp BridgeToken.abi "${ethereumYccBridgeTokenAddr}.abi"
}
function deploy_erc20_chain33_ZBC() {
# chain33 token create ZBC
echo -e "${GRE}======= 在 chain33 上创建 ERC20 ZBC ======${NOC}"
result=$(${CLIA} chain33 token create -s ZBC -o "${chain33DeployAddr}")
cli_ret "${result}" "chain33 token create -s ZBC"
chain33ZbcERC20TokenAddr=$(echo "${result}" | jq -r .msg)
cp ERC20.abi "${chain33ZbcERC20TokenAddr}.abi"
# echo 'ZBC.1:增加allowance的设置,或者使用relayer工具进行'
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33ZbcERC20TokenAddr}" -p "approve(${chain33BridgeBank}, 330000000000)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
# echo 'ZBC.2:#执行add lock操作:addToken2LockList'
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33BridgeBank}" -p "addToken2LockList(${chain33ZbcERC20TokenAddr}, ZBC)" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
}
function create_bridge_token_eth_ZBC() {
# ethereum create-bridge-token ZBC
echo -e "${GRE}======= 在 ethereum 上创建 bridgeToken ZBC ======${NOC}"
result=$(${CLIA} ethereum token create-bridge-token -s ZBC)
cli_ret "${result}" "ethereum token create -s ZBC"
ethereumZbcBridgeTokenAddr=$(echo "${result}" | jq -r .addr)
cp BridgeToken.abi "${ethereumZbcBridgeTokenAddr}.abi"
}
# shellcheck disable=SC2120
function InitTokenAddr() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
create_bridge_token_eth_BTY
create_bridge_token_chain33_ETH
deploy_erc20_eth_YCC
create_bridge_token_chain33_YCC
deploy_erc20_chain33_YCC
create_bridge_token_eth_YCC
deploy_erc20_chain33_ZBC
create_bridge_token_eth_ZBC
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function start_ebrelayerA() {
nohup ./ebrelayer ./relayer.toml >cross2ethA.log 2>&1 &
sleep 2
}
# start ebrelayer B C D
function updata_toml_start_BCD() {
bind_port=9901
push_port=20000
for name in b c d; do
local file="./relayer_$name/relayer.toml"
cp './relayer.toml' "${file}"
# 删除配置文件中不需要的字段
for deleteName in "deploy4chain33" "deployerPrivateKey" "operatorAddr" "validatorsAddr" "initPowers" "deploy" "deployerPrivateKey" "operatorAddr" "validatorsAddr" "initPowers"; do
delete_line "${file}" "${deleteName}"
done
bind_port=$((bind_port + 1))
line=$(delete_line_show "./relayer_$name/relayer.toml" "JrpcBindAddr")
if [ "${line}" ]; then
sed -i ''"${line}"' a JrpcBindAddr="localhost:'${bind_port}'"' "./relayer_$name/relayer.toml"
fi
push_port=$((push_port + 1))
line=$(delete_line_show "./relayer_$name/relayer.toml" "pushHost")
if [ "${line}" ]; then
sed -i ''"${line}"' a pushHost="http://localhost:'${push_port}'"' "./relayer_$name/relayer.toml"
fi
line=$(delete_line_show "./relayer_$name/relayer.toml" "pushBind")
if [ "${line}" ]; then
sed -i ''"${line}"' a pushBind="0.0.0.0:'${push_port}'"' "./relayer_$name/relayer.toml"
fi
sleep 1
pushNameChange "./relayer_$name/relayer.toml"
nohup ./relayer_$name/ebrelayer ./relayer_$name/relayer.toml >./relayer_$name/cross2eth_$name.log 2>&1 &
sleep 2
CLI="./ebcli_$name"
result=$(${CLI} set_pwd -p 123456hzj)
cli_ret "${result}" "set_pwd"
result=$(${CLI} unlock -p 123456hzj)
cli_ret "${result}" "unlock"
eval chain33ValidatorKey=\$chain33ValidatorKey${name}
# shellcheck disable=SC2154
result=$(${CLI} chain33 import_privatekey -k "${chain33ValidatorKey}")
cli_ret "${result}" "chain33 import_privatekey"
eval ethValidatorAddrKey=\$ethValidatorAddrKey${name}
# shellcheck disable=SC2154
result=$(${CLI} ethereum import_privatekey -k "${ethValidatorAddrKey}")
cli_ret "${result}" "ethereum import_privatekey"
done
}
function validators_config() {
# 修改 relayer.toml 配置文件 initPowers
# shellcheck disable=SC2155
line=$(delete_line_show "./relayer.toml" 'initPowers=\[96, 1, 1, 1\]')
if [ "${line}" ]; then
sed -i ''"${line}"' a initPowers=[25, 25, 25, 25]' "./relayer.toml"
fi
line=$(delete_line_show "./relayer.toml" 'initPowers=\[96, 1, 1, 1\]')
if [ "${line}" ]; then
sed -i ''"${line}"' a initPowers=[25, 25, 25, 25]' "./relayer.toml"
fi
line=$(delete_line_show "./relayer.toml" 'operatorAddr="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"')
if [ "${line}" ]; then
sed -i ''"${line}"' a operatorAddr='\""${chain33DeployAddr}"\"'' "./relayer.toml"
fi
line=$(delete_line_show "./relayer.toml" 'deployerPrivateKey="0xcc38546e9e659d15e6b4893f0ab32a06d103931a8230b0bde71459d2b27d6944"')
if [ "${line}" ]; then
sed -i ''"${line}"' a deployerPrivateKey='\""${chain33DeployKey}"\"'' "./relayer.toml"
fi
line=$(delete_line_show "./relayer.toml" 'validatorsAddr=\["14KEKbYtKKQm4wMthSK9J4La4nAiidGozt')
if [ "${line}" ]; then
# shellcheck disable=SC2154
sed -i ''"${line}"' a validatorsAddr=['\""${chain33Validatora}"\"', '\""${chain33Validatorb}"\"', '\""${chain33Validatorc}"\"', '\""${chain33Validatord}"\"']' "./relayer.toml"
fi
}
function StartRelayerAndDeploy() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# 修改 relayer.toml 配置文件 pushName 字段
pushNameChange "./relayer.toml"
validators_config
# 启动 ebrelayer
start_ebrelayerA
# 导入私钥 部署合约 设置 bridgeRegistry 地址
InitAndDeploy
# 重启
kill_ebrelayer ebrelayer
start_ebrelayerA
result=$(${CLIA} unlock -p 123456hzj)
cli_ret "${result}" "unlock"
# start ebrelayer B C D
updata_toml_start_BCD
# 设置 token 地址
InitTokenAddr
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# chian33 初始化准备
function InitChain33() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# init
${Chain33Cli} seed save -p 1314fuzamei -s "tortoise main civil member grace happy century convince father cage beach hip maid merry rib"
${Chain33Cli} wallet unlock -p 1314fuzamei -t 0
${Chain33Cli} account import_key -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944 -l returnAddr
# shellcheck disable=SC2154
${Chain33Cli} account import_key -k "${chain33ReceiverAddrKey}" -l minerAddr
# shellcheck disable=SC2154
hash=$(${Chain33Cli} send coins transfer -a 10000 -n test -t "${chain33ReceiverAddr}" -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944)
check_tx "${Chain33Cli}" "${hash}"
InitChain33Validator
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# $1 Key $2 addr $3 label $4 amount $5 evm amount
function Chain33ImportKey() {
local key="${1}"
local addr="${2}"
local label="${3}"
local amount="${4}"
local evm_amount="${5}"
# 转帐到 DeployAddr 需要手续费
result=$(${Chain33Cli} account import_key -k "${key}" -l "${label}")
check_addr "${result}" "${addr}"
hash=$(${Chain33Cli} send coins transfer -a "${amount}" -n test -t "${addr}" -k 4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01)
check_tx "${Chain33Cli}" "${hash}"
# 转账到 EVM 合约中
hash=$(${Chain33Cli} send coins send_exec -e evm -a "${evm_amount}" -k "${addr}")
check_tx "${Chain33Cli}" "${hash}"
result=$(${Chain33Cli} account balance -a "${addr}" -e evm)
# balance_ret "${result}" "${evm_amount}.0000" # 平行链查询方式不一样 直接去掉金额匹配
}
# chian33 初始化准备
function InitChain33Validator() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# 转帐到 DeployAddr 需要手续费
Chain33ImportKey "${chain33DeployKey}" "${chain33DeployAddr}" "DeployAddr" 2200 1000
# shellcheck disable=SC2154
{
# 转帐到 chain33TestAddrKey 需要手续费
Chain33ImportKey "${chain33TestAddrKey1}" "${chain33TestAddr1}" "cross2ethAddr1" 2200 1000
Chain33ImportKey "${chain33TestAddrKey2}" "${chain33TestAddr2}" "cross2ethAddr2" 2200 1000
}
# 导入 chain33Validators 私钥生成地址
for name in a b c d; do
eval chain33ValidatorKey=\$chain33ValidatorKey${name}
eval chain33Validator=\$chain33Validator${name}
result=$(${Chain33Cli} account import_key -k "${chain33ValidatorKey}" -l validator$name)
# shellcheck disable=SC2154
check_addr "${result}" "${chain33Validator}"
# chain33Validator 要有手续费
hash=$(${Chain33Cli} send coins transfer -a 100 -t "${chain33Validator}" -k 4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01)
check_tx "${Chain33Cli}" "${hash}"
result=$(${Chain33Cli} account balance -a "${chain33Validator}" -e coins)
# balance_ret "${result}" "100.0000" # 平行链查询方式不一样 直接去掉金额匹配
done
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function StartChain33() {
kill_ebrelayer chain33
sleep 2
# delete chain33 datadir
rm ../../datadir ../../logs -rf
nohup ../../chain33 -f ./ci/bridgevmxgo/test.toml >chain33log.log 2>&1 &
sleep 1
InitChain33
}
function AllRelayerStart() {
kill_all_ebrelayer
StartRelayerAndDeploy
}
function StartOneRelayer() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
kill_ebrelayer ebrelayer
sleep 10
rm datadir/ logs/ -rf
# 修改 relayer.toml 配置文件 pushName 字段
pushNameChange "./relayer.toml"
# 启动 ebrelayer
start_ebrelayerA
# 导入私钥 部署合约 设置 bridgeRegistry 地址
InitAndDeploy
# 重启
kill_ebrelayer ebrelayer
start_ebrelayerA
result=$(${CLIA} unlock -p 123456hzj)
cli_ret "${result}" "unlock"
# 设置 token 地址
InitTokenAddr
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function StartRelayerOnRopsten() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function initMultisignChain33Addr() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
for name in A B C D; do
eval chain33MultisignKey=\$chain33MultisignKey${name}
eval chain33Multisign=\$chain33Multisign${name}
# shellcheck disable=SC2154
result=$(${Chain33Cli} account import_key -k "${chain33MultisignKey}" -l multisignAddr$name)
# shellcheck disable=SC2154
check_addr "${result}" "${chain33Multisign}"
# chain33Multisign 要有手续费
hash=$(${Chain33Cli} send coins transfer -a 10 -t "${chain33Multisign}" -k "${chain33DeployAddr}")
check_tx "${Chain33Cli}" "${hash}"
result=$(${Chain33Cli} account balance -a "${chain33Multisign}" -e coins)
balance_ret "${result}" "10.0000"
done
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function deployChain33AndEthMultisign() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== 部署 chain33 离线钱包合约 ===========${NOC}"
result=$(${CLIA} chain33 multisign deploy)
cli_ret "${result}" "chain33 multisign deploy"
multisignChain33Addr=$(echo "${result}" | jq -r ".msg")
echo -e "${GRE}=========== 部署 ETH 离线钱包合约 ===========${NOC}"
result=$(${CLIA} ethereum multisign deploy)
cli_ret "${result}" "ethereum multisign deploy"
multisignEthAddr=$(echo "${result}" | jq -r ".msg")
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function setupChain33Multisign() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== 设置 chain33 离线钱包合约 ===========${NOC}"
result=$(${CLIA} chain33 multisign setup -k "${chain33DeployKey}" -o "${chain33MultisignA},${chain33MultisignB},${chain33MultisignC},${chain33MultisignD}")
cli_ret "${result}" "chain33 multisign setup"
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33DeployAddr}" -e "${chain33BridgeBank}" -p "configOfflineSaveAccount(${multisignChain33Addr})" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function setupEthMultisign() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}=========== 设置 ETH 离线钱包合约 ===========${NOC}"
result=$(${CLIA} ethereum multisign setup -k "${ethDeployKey}" -o "${ethMultisignA},${ethMultisignB},${ethMultisignC},${ethMultisignD}")
cli_ret "${result}" "ethereum multisign setup"
result=$(${CLIA} ethereum multisign set_offline_addr -s "${multisignEthAddr}")
cli_ret "${result}" "set_offline_addr"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function transferChain33MultisignFee() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# multisignChain33Addr 要有手续费
hash=$(${Chain33Cli} send coins transfer -a 10 -t "${multisignChain33Addr}" -k "${chain33DeployAddr}")
check_tx "${Chain33Cli}" "${hash}"
result=$(${Chain33Cli} account balance -a "${multisignChain33Addr}" -e coins)
balance_ret "${result}" "10.0000"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function deployMultisign() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
initMultisignChain33Addr
deployChain33AndEthMultisign
setupChain33Multisign
setupEthMultisign
transferChain33MultisignFee
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# lock bty 判断是否转入多签地址金额是否正确
function lock_bty_multisign() {
local lockAmount=$1
local lockAmount2="${1}00000000"
hash=$(${Chain33Cli} send evm call -f 1 -a "${lockAmount}" -k "${chain33DeployAddr}" -e "${chain33BridgeBank}" -p "lock(${ethDeployAddr}, ${chain33BtyERC20TokenAddr}, ${lockAmount2})" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
if [[ $# -eq 3 ]]; then
local bridgeBankBalance=$2
local multisignBalance=$3
result=$(${Chain33Cli} account balance -a "${chain33BridgeBank}" -e evm)
balance_ret "${result}" "${bridgeBankBalance}"
result=$(${Chain33Cli} account balance -a "${multisignChain33Addr}" -e evm)
balance_ret "${result}" "${multisignBalance}"
fi
}
# lock chain33 ycc erc20 判断是否转入多签地址金额是否正确
function lock_chain33_ycc_multisign() {
local lockAmount="${1}00000000"
# shellcheck disable=SC2154
hash=$(${Chain33Cli} send evm call -f 1 -k "${chain33TestAddr1}" -e "${chain33BridgeBank}" -p "lock(${ethTestAddr1}, ${chain33YccERC20TokenAddr}, ${lockAmount})" --chainID "${chain33ID}")
check_tx "${Chain33Cli}" "${hash}"
if [[ $# -eq 3 ]]; then
local bridgeBankBalance="${2}00000000"
local multisignBalance="${3}00000000"
if [[ ${3} == "0" ]]; then
multisignBalance="0"
fi
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${chain33BridgeBank}" -b "balanceOf(${chain33BridgeBank})")
is_equal "${result}" "${bridgeBankBalance}"
result=$(${Chain33Cli} evm query -a "${chain33YccERC20TokenAddr}" -c "${multisignChain33Addr}" -b "balanceOf(${multisignChain33Addr})")
is_equal "${result}" "${multisignBalance}"
fi
}
# lock eth 判断是否转入多签地址金额是否正确
function lock_eth_multisign() {
local lockAmount=$1
# shellcheck disable=SC2154
result=$(${CLIA} ethereum lock -m "${lockAmount}" -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}")
cli_ret "${result}" "lock"
if [[ $# -eq 3 ]]; then
local bridgeBankBalance=$2
local multisignBalance=$3
# eth 等待 2 个区块
sleep 4
# eth_block_wait 2
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}")
cli_ret "${result}" "balance" ".balance" "${bridgeBankBalance}"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}")
cli_ret "${result}" "balance" ".balance" "${multisignBalance}"
fi
}
# lock ethereum ycc erc20 判断是否转入多签地址金额是否正确
function lock_ethereum_ycc_multisign() {
local lockAmount=$1
result=$(${CLIA} ethereum lock -m "${lockAmount}" -k "${ethTestAddrKey1}" -r "${chain33ReceiverAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "lock"
if [[ $# -eq 3 ]]; then
local bridgeBankBalance=$2
local multisignBalance=$3
# eth 等待 2 个区块
sleep 4
# eth_block_wait 2
result=$(${CLIA} ethereum balance -o "${ethBridgeBank}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "${bridgeBankBalance}"
result=$(${CLIA} ethereum balance -o "${multisignEthAddr}" -t "${ethereumBycERC20TokenAddr}")
cli_ret "${result}" "balance" ".balance" "${multisignBalance}"
fi
}
# 检查交易是否执行成功 $1:交易hash
function check_eth_tx() {
local tx=${1}
ty=$(${CLIA} ethereum receipt -s "${tx}" | jq .status | sed 's/\"//g')
if [[ ${ty} != 0x1 ]]; then
echo -e "${RED}check eth tx error, hash is ${tx}${NOC}"
exit_cp_file
fi
}
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
set -x
set +e
# 主要在平行链上测试
source "./offlinePublic.sh"
# shellcheck disable=SC2034
{
# ETH 部署合约者的私钥 用于部署合约时签名使用
ethDeployAddr="0x8AFDADFC88a1087c9A1D6c0F5Dd04634b87F303a"
ethDeployKey="0x8656d2bc732a8a816a461ba5e2d8aac7c7f85c26a813df30d5327210465eb230"
# chain33 部署合约者的私钥 用于部署合约时签名使用
chain33DeployAddr="1JxhYLYsrscjTaQfaMoVUrnSdrejP7XRQD"
chain33DeployKey="0x9ef82623a5e9aac58d3a6b06392af66ec77289522b28896aed66abaaede66903"
# validatorsAddr=["0x92C8b16aFD6d423652559C6E266cBE1c29Bfd84f", "0x0df9a824699bc5878232c9e612fe1a5346a5a368", "0xcb074cb21cdddf3ce9c3c0a7ac4497d633c9d9f1", "0xd9dab021e74ecf475788ed7b61356056b2095830"]# shellcheck disable=SC2034
# eth 验证者私钥
ethValidatorAddra="0x92C8b16aFD6d423652559C6E266cBE1c29Bfd84f"
ethValidatorAddrb="0x0df9a824699bc5878232c9e612fe1a5346a5a368"
ethValidatorAddrc="0xcb074cb21cdddf3ce9c3c0a7ac4497d633c9d9f1"
ethValidatorAddrd="0xd9dab021e74ecf475788ed7b61356056b2095830"
ethValidatorAddrKeya="3fa21584ae2e4fd74db9b58e2386f5481607dfa4d7ba0617aaa7858e5025dc1e"
ethValidatorAddrKeyb="a5f3063552f4483cfc20ac4f40f45b798791379862219de9e915c64722c1d400"
ethValidatorAddrKeyc="bbf5e65539e9af0eb0cfac30bad475111054b09c11d668fc0731d54ea777471e"
ethValidatorAddrKeyd="c9fa31d7984edf81b8ef3b40c761f1847f6fcd5711ab2462da97dc458f1f896b"
# 新增地址 chain33 需要导入地址 转入 10 bty当收费费
chain33Validatora="1N6HstkyLFS8QCeVfdvYxx1xoryXoJtvvZ"
chain33Validatorb="155ooMPBTF8QQsGAknkK7ei5D78rwDEFe6"
chain33Validatorc="13zBdQwuyDh7cKN79oT2odkxYuDbgQiXFv"
chain33Validatord="113ZzVamKfAtGt9dq45fX1mNsEoDiN95HG"
chain33ValidatorKeya="0x027ca96466c71c7e7c5d73b7e1f43cb889b3bd65ebd2413eefd31c6709c262ae"
chain33ValidatorKeyb="0x9d539bc5fd084eb7fe86ad631dba9aa086dba38418725c38d9751459f567da66"
chain33ValidatorKeyc="0x0a6671f101e30a2cc2d79d77436b62cdf2664ed33eb631a9c9e3f3dd348a23be"
chain33ValidatorKeyd="0x3818b257b05ee75b6e43ee0e3cfc2d8502342cf67caed533e3756966690b62a5"
ethTestAddr1=0xbc333839E37bc7fAAD0137aBaE2275030555101f
ethTestAddrKey1=0x0c61f5a879d70807686e43eccc1f52987a15230ae0472902834af4d1933674f2
ethTestAddr2=0x495953A743ef169EC5D4aC7b5F786BF2Bd56aFd5
ethTestAddrKey2=0x2809477ede1261da21270096776ba7dc68b89c9df5f029965eaa5fe7f0b80697
ethReceiverAddr1="0xa4ea64a583f6e51c3799335b28a8f0529570a635"
#ethReceiverAddrKey1="355b876d7cbcb930d5dfab767f66336ce327e082cbaa1877210c1bae89b1df71"
chain33TestAddr1="1Cj1rqUenPmkeD6A8MGEzkBKQFN2H9yL3x"
chain33TestAddrKey1="0x7269a7a87d476310da37a9ca1ddc9333c9d7a0dfe1f2998b84758843a895433b"
chain33TestAddr2="1BCGLhdcdthNutQowV2YShuuN9fJRRGLxu"
chain33TestAddrKey2="0xb74acfd4eebbbd07bcae212baa7f094235ab8dc04f2f1d828681477b98b24008"
chain33ReceiverAddr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
chain33ReceiverAddrKey="4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01"
chain33BridgeBank=""
ethBridgeBank=""
chain33BtyERC20TokenAddr="1111111111111111111114oLvT2"
chain33EthBridgeTokenAddr=""
ethereumBtyBridgeTokenAddr=""
chain33BycBridgeTokenAddr=""
ethereumBycERC20TokenAddr=""
BridgeRegistryOnChain33=""
chain33YccERC20TokenAddr=""
BridgeRegistryOnEth=""
ethereumYccBridgeTokenAddr=""
chain33ZbcERC20TokenAddr=""
ethereumZbcBridgeTokenAddr=""
multisignChain33Addr=""
multisignEthAddr=""
Chain33Cli=""
maturityDegree=10
chain33ID=0
}
# shellcheck disable=SC2120
function offline_set_offline_token_Bty() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== chain33 端 configLockedTokenOfflineSave BTY ======${NOC}"
# echo '2:#配置自动转离线钱包(bty, 100, 50%)'
local threshold=10000000000
local percents=50
if [[ $# -eq 2 ]]; then
threshold=$1
percents=$2
fi
# shellcheck disable=SC2086
${Boss4xCLI} chain33 offline set_offline_token -c "${chain33BridgeBank}" -s BTY -m ${threshold} -p ${percents} -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "chain33_set_offline_token.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# shellcheck disable=SC2120
function offline_set_offline_token_Chain33Ycc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
echo -e "${GRE}===== chain33 端 configLockedTokenOfflineSave ERC20 YCC ======${NOC}"
# echo '2:#配置自动转离线钱包(YCC, 100, 60%)'
local threshold=10000000000
local percents=60
if [[ $# -eq 2 ]]; then
threshold=$1
percents=$2
fi
# shellcheck disable=SC2086
${Boss4xCLI} chain33 offline set_offline_token -c "${chain33BridgeBank}" -t "${chain33YccERC20TokenAddr}" -s YCC -m ${threshold} -p ${percents} -k "${chain33DeployKey}" --chainID "${chain33ID}"
chain33_offline_send "chain33_set_offline_token.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# shellcheck disable=SC2120
function offline_set_offline_token_Eth() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
# echo '2:#配置自动转离线钱包(eth, 20, 50%)'
local threshold=20
local percents=50
if [[ $# -eq 2 ]]; then
threshold=$1
percents=$2
fi
# shellcheck disable=SC2086
${Boss4xCLI} ethereum offline set_offline_token -s ETH -m ${threshold} -p ${percents} -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "set_offline_token.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
# shellcheck disable=SC2120
function offline_set_offline_token_EthYcc() {
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
local threshold=100
local percents=40
if [[ $# -eq 2 ]]; then
threshold=$1
percents=$2
fi
# shellcheck disable=SC2086
${Boss4xCLI} ethereum offline set_offline_token -s BYC -m ${threshold} -p ${percents} -t "${ethereumBycERC20TokenAddr}" -c "${ethBridgeBank}" -d "${ethDeployAddr}"
ethereum_offline_sign_send "set_offline_token.txt"
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
function MainTest() {
set +e
chain33ID=0
chain33BridgeBank=15Myyvq97WinTWto8zcEdm838zXmvJKfnX
ethBridgeBank=0xC65B02a22B714b55D708518E2426a22ffB79113d
# ethereumBtyBridgeTokenAddr=0x9c3d40a44a2f61ef8d46fa8c7a731c08fb16ccef
# chain33EthBridgeTokenAddr=1JVFbJhFUWUNH41PxbV7NqwUd3F9BJ3nqV
ethereumBycERC20TokenAddr=0x20a32A5680EBf55740B0C98B54cDE8e6FD5a4FB0
# ethereumYccBridgeTokenAddr=0x05f3f31c7d53bcb71a6487dff3115d86370698bd
# chain33BycBridgeTokenAddr=1BdREGqsjbcKkvRheXWYKRq37vJHMs22Uy
chain33YccERC20TokenAddr=17yu1yULdGFddUz26PEeaHpJtkFGEpzYrA
# chain33ZbcERC20TokenAddr=1AqRwUa4T3q9DuCyUwn5ucHgtUhbUP2yfu
# ethereumZbcBridgeTokenAddr=0x89bb32184e466a9c8ea50c31174b575c2bcd64c2
dockerNamePrefix="build"
docker_chain33_ip=$(get_docker_addr "${dockerNamePrefix}_chain33_1")
# MainCli="./chain33-cli --rpc_laddr http://${docker_chain33_ip}:8801"
# Para8801Cli="./chain33-cli --rpc_laddr http://${docker_chain33_ip}:8901 --paraName user.p.para."
Para8901Cli="./chain33-cli --rpc_laddr http://${docker_chain33_ip}:8901 --paraName user.p.para."
# shellcheck disable=SC2034
{
CLIA="docker exec ${dockerNamePrefix}_ebrelayera_1 /root/ebcli_A"
CLIB="docker exec ${dockerNamePrefix}_ebrelayerb_1 /root/ebcli_A"
CLIC="docker exec ${dockerNamePrefix}_ebrelayerc_1 /root/ebcli_A"
CLID="docker exec ${dockerNamePrefix}_ebrelayerd_1 /root/ebcli_A"
docker_ganachetest_ip=$(get_docker_addr "${dockerNamePrefix}_ganachetest_1")
Boss4xCLI="docker exec ${dockerNamePrefix}_ebrelayera_1 /root/boss4x --rpc_laddr http://${docker_chain33_ip}:8901 --rpc_laddr_ethereum http://${docker_ganachetest_ip}:8545 --paraName user.p.para."
echo "${Boss4xCLI}"
}
# shellcheck disable=SC2034
Chain33Cli=${Para8901Cli}
# 离线多签地址转入阈值设大
offline_set_offline_token_Bty 100000000000000 10
offline_set_offline_token_Chain33Ycc 100000000000000 10
offline_set_offline_token_Eth 100000000000000 10
offline_set_offline_token_EthYcc 100000000000000 10
echo -e "${GRE}=========== $FUNCNAME end ===========${NOC}"
}
MainTest
#!/usr/bin/env bash
# shellcheck disable=SC2050
# shellcheck source=/dev/null
set -x
set +e
while [ 1 == 1 ]; do
sleep 100
done
Title="local"
TestNet=true
CoinSymbol="bty"
TxHeight=true
ChainID=33
# crypto模块配置
[crypto]
enableTypes=[] #设置启用的加密插件名称,不配置启用所有
[crypto.enableHeight] #配置已启用插件的启用高度,不配置采用默认高度0, 负数表示不启用
secp256k1=0
[crypto.sub.secp256k1] #支持插件子配置
[log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
loglevel = "debug"
logConsoleLevel = "info"
# 日志文件名,可带目录,所有生成的日志文件都放到此目录下
logFile = "logs/chain33.log"
# 单个日志文件的最大值(单位:兆)
maxFileSize = 20
# 最多保存的历史日志文件个数
maxBackups = 20
# 最多保存的历史日志消息(单位:天)
maxAge = 28
# 日志文件名是否使用本地事件(否则使用UTC时间)
localTime = true
# 历史日志文件是否压缩(压缩格式为gz)
compress = false
# 是否打印调用源文件和行号
callerFile = true
# 是否打印调用方法
callerFunction = true
[blockchain]
defCacheSize=128
maxFetchBlockNum=128
timeoutSeconds=5
batchBlockNum=128
driver="leveldb"
dbPath="datadir"
dbCache=64
isStrongConsistency=true
singleMode=true
batchsync=false
isRecordBlockSequence=true
isParaChain=false
enableTxQuickIndex=true
# 使能精简localdb
enableReduceLocaldb=false
# 关闭分片存储,默认false为开启分片存储;平行链不需要分片需要修改此默认参数为true
disableShard=false
# 分片存储中每个大块包含的区块数
chunkblockNum=1000
# 使能从P2pStore中获取数据
enableFetchP2pstore=false
# 使能假设已删除已归档数据后,获取数据情况
enableIfDelLocalChunk=false
# 开启推送功能
enablePushSubscribe=true
[p2p]
types=[ "dht"]
enable=true
driver="leveldb"
dbPath="datadir/addrbook"
dbCache=4
grpcLogFile="grpc33.log"
[p2p.sub.dht]
port=13803
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
enableTLS=false
certFile="cert.pem"
keyFile="key.pem"
[mempool]
name="timeline"
poolCacheSize=10240
# 最小得交易手续费率,这个没有默认值,必填,一般是0.001 coins
minTxFeeRate=100000
# 最大的交易手续费率, 0.1 coins
maxTxFeeRate=10000000
# 单笔交易最大的手续费, 10 coins
maxTxFee=1000000000
maxTxNumPerAccount=100
isLevelFee=false
[mempool.sub.timeline]
poolCacheSize=10240
[mempool.sub.score]
poolCacheSize=10240
timeParam=1 #时间占价格比例
priceConstant=1544 #手续费相对于时间的一个合适的常量,取当前unxi时间戳前四位数,排序时手续费高1e-5~=快1s
pricePower=1 #常量比例
[mempool.sub.price]
poolCacheSize=10240
[consensus]
name="solo"
minerstart=true
genesisBlockTime=1514533394
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
minerExecs=["ticket", "autonomy"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits = "0x1f00ffff"
maxTxNumber = 1600 #160
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[mver.consensus.ticket]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ticket.ForkChainParamV1]
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[consensus.sub.solo]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
hotkeyAddr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
waitTxMs=10
[consensus.sub.ticket]
genesisBlockTime=1514533394
[[consensus.sub.ticket.genesis]]
minerAddr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
returnAddr="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
count=10000
[[consensus.sub.ticket.genesis]]
minerAddr="1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"
returnAddr="1EbDHAXpoiewjPLX9uqoz38HsKqMXayZrF"
count=10000
[[consensus.sub.ticket.genesis]]
minerAddr="1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX"
returnAddr="1KcCVZLSQYRUwE5EXTsAoQs9LuJW6xwfQa"
count=10000
[store]
name="mavl"
driver="leveldb"
dbPath="datadir/mavltree"
dbCache=128
[store.sub.mavl]
enableMavlPrefix=false
enableMVCC=false
enableMavlPrune=false
pruneHeight=10000
# 是否使能mavl数据载入内存
enableMemTree=false
# 是否使能mavl叶子节点数据载入内存
enableMemVal=false
# 缓存close ticket数目,该缓存越大同步速度越快,最大设置到1500000
tkCloseCacheLen=100000
[wallet]
minFee=1000000
driver="leveldb"
dbPath="datadir/wallet"
dbCache=16
signType="secp256k1"
coinType="bty"
[wallet.sub.ticket]
minerwhitelist=["*"]
[exec]
enableStat=false
enableMVCC=false
[exec.sub.token]
saveTokenTxList=true
tokenApprs = [
"1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK",
"1LY8GFia5EiyoTodMLfkB5PHNNpXRqxhyB",
"1GCzJDS6HbgTQ2emade7mEJGGWFfA15pS9",
"1JYB8sxi4He5pZWHCd3Zi2nypQ4JMB6AxN",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
]
[exec.sub.relay]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
[exec.sub.cert]
# 是否启用证书验证和签名
enable=false
# 加密文件路径
cryptoPath="authdir/crypto"
# 带证书签名类型,支持"auth_ecdsa", "auth_sm2"
signType="auth_ecdsa"
[exec.sub.manage]
superManager=[
"1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
]
[exec.sub.autonomy]
total="16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
useBalance=false
[health]
listenAddr="localhost:8805"
checkInterval=1
unSyncMaxTimes=2
[metrics]
#是否使能发送metrics数据的发送
enableMetrics=false
#数据保存模式
dataEmitMode="influxdb"
[metrics.sub.influxdb]
#以纳秒为单位的发送间隔
duration=1000000000
url="http://influxdb:8086"
database="chain33metrics"
username=""
password=""
namespace=""
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
#source "./dockerRelayerTest.sh"
source "./dockerRelayerTestEvm.sh"
#source "./dockerRelayerTestInfinite.sh"
source "./paracrosstestcase.sh"
function bridgevmxgo() {
if [ "${2}" == "init" ]; then
para_init "${3}"
elif [ "${2}" == "config" ]; then
para_set_wallet
para_transfer
elif [ "${2}" == "test" ]; then
echo "========================== bridgevmxgo test =========================="
set +e
set -x
para_create_nodegroup
AllRelayerMainTest 10
# perf_test_main 1
echo "========================== bridgevmxgo test end =========================="
fi
}
#!/usr/bin/env bash
#shellcheck disable=SC2128
#shellcheck source=/dev/null
set -x
source ../dapp-test-common.sh
MAIN_HTTP=""
function rpc_test() {
chain33_RpcTestBegin bridgevmxgo
MAIN_HTTP="$1"
echo "main_ip=$MAIN_HTTP"
chain33_RpcTestRst bridgevmxgo "$CASE_ERR"
}
chain33_debug_function rpc_test "$1" "$2"
pragma solidity ^0.5.0;
import "./GoAssetBank.sol";
import "./EvmAssetBank.sol";
import "../Oracle.sol";
import "../GoAssetBridge.sol";
/**
* @title BridgeBank
* @dev Bank contract which coordinates asset-related functionality.
* GoAssetBank manages the minting and burning of tokens which
* represent go contract issued assets, while EvmAssetBank manages
* the locking and unlocking of Chain33 and ERC20 token assets
* based on Chain33.
**/
contract BridgeBank is GoAssetBank, EvmAssetBank {
using SafeMath for uint256;
address public operator;
Oracle public oracle;
GoAssetBridge public goAssetBridge;
/*
* @dev: Constructor, sets operator
*/
constructor (
address _operatorAddress,
address _oracleAddress,
address _goAssetBridgeAddress
)
public
{
operator = _operatorAddress;
oracle = Oracle(_oracleAddress);
goAssetBridge = GoAssetBridge(_goAssetBridgeAddress);
}
/*
* @dev: Modifier to restrict access to operator
*/
modifier onlyOperator() {
require(
msg.sender == operator,
'Must be BridgeBank operator.'
);
_;
}
/*
* @dev: Modifier to restrict access to Offline
*/
modifier onlyOffline() {
require(
msg.sender == offlineSave,
'Must be onlyOffline.'
);
_;
}
/*
* @dev: Modifier to restrict access to the oracle
*/
modifier onlyOracle()
{
require(
msg.sender == address(oracle),
"Access restricted to the oracle"
);
_;
}
/*
* @dev: Modifier to restrict access to the goAsset bridge
*/
modifier onlyGoAssetBridge()
{
require(
msg.sender == address(goAssetBridge),
"Access restricted to the goAsset bridge"
);
_;
}
/*
* @dev: Modifier to make sure this symbol not created now
*/
modifier onlyBridgeToken(address _token)
{
require(
(address(0) != _token) && (msg.value == 0),
"Only bridge token could be locked and tranfer to contract:evmxgo"
);
_;
}
/*
* @dev: Fallback function allows operator to send funds to the bank directly
* This feature is used for testing and is available at the operator's own risk.
*/
function() external payable onlyOffline {}
/*
* @dev: Creates a new BridgeToken
*
* @param _symbol: The new BridgeToken's symbol
* @return: The new BridgeToken contract's address
*/
function createNewBridgeToken(
string memory _symbol
)
public
onlyOperator
returns(address)
{
return deployNewBridgeToken(_symbol);
}
/*
* @dev: Mints new BankTokens
*
* @param _goAssetSender: The goAsset sender's address.
* @param _chain33Recipient: The intended recipient's Chain33 address.
* @param _bridgeTokenAddress: The bridge token address
* @param _symbol: goAsset token symbol
* @param _amount: number of goAsset tokens to be minted
*/
function mintBridgeTokens(
address _goAssetSender,
address payable _intendedRecipient,
address _bridgeTokenAddress,
string memory _symbol,
uint256 _amount
)
public
onlyGoAssetBridge
{
return mintNewBridgeTokens(
_goAssetSender,
_intendedRecipient,
_bridgeTokenAddress,
_symbol,
_amount
);
}
/*
* @dev: Burns bank tokens
*
* @param _goAssetReceiver: The _goAsset receiver address in bytes.
* @param _goAssetTokenAddress: The currency type
* @param _amount: number of goAsset tokens to be burned
*/
function burnBridgeTokens(address _goAssetReceiver, address _goAssetTokenAddress, uint256 _amount) public
{
return burnGoAssetTokens(
msg.sender,
_goAssetReceiver,
_goAssetTokenAddress,
_amount
);
}
/*
* @dev: addToken2LockList used to add token with the specified address to be
* allowed locked from GoAsset
*
* @param _token: token contract address
* @param _symbol: token symbol
*/
function addToken2LockList(
address _token,
string memory _symbol
)
public
onlyOperator
{
addToken2AllowLock(_token, _symbol);
}
/*
* @dev: configTokenOfflineSave used to config threshold to trigger tranfer token to offline account
* when the balance of locked token reaches
*
* @param _token: token contract address
* @param _symbol:token symbol,just used for double check that token address and symbol is consistent
* @param _threshold: _threshold to trigger transfer
* @param _percents: amount to transfer per percents of threshold
*/
function configLockedTokenOfflineSave(
address _token,
string memory _symbol,
uint256 _threshold,
uint8 _percents
)
public
onlyOperator
{
if (address(0) != _token) {
require(keccak256(bytes(BridgeToken(_token).symbol())) == keccak256(bytes(_symbol)), "token address and symbol is not consistent");
} else {
require(keccak256(bytes("BTY")) == keccak256(bytes(_symbol)), "token address and symbol is not consistent");
}
configOfflineSave4Lock(_token, _symbol, _threshold, _percents);
}
/*
* @dev: configOfflineSaveAccount used to config offline account to receive token
* when the balance of locked token reaches threshold
*
* @param _offlineSave: receiver address
*/
function configOfflineSaveAccount(address payable _offlineSave) public onlyOperator
{
offlineSave = _offlineSave;
}
/*
* @dev: Locks received Chain33 funds.
*
* @param _recipient: bytes representation of destination address.
* @param _token: token address in origin chain (0x0 if chain33)
* @param _amount: value of deposit
*/
function lock(
address _recipient,
address _token,
uint256 _amount
)
public
availableNonce()
onlyBridgeToken(_token)
payable
{
string memory symbol;
require(
BridgeToken(_token).transferFrom(msg.sender, address(this), _amount),
"Contract token allowances insufficient to complete this lock request"
);
// Set symbol to the ERC20 token's symbol
symbol = BridgeToken(_token).symbol();
require(
tokenAllow2Lock[keccak256(abi.encodePacked(symbol))] == _token,
'The token is not allowed to be locked from Chain33.'
);
lockFunds(
msg.sender,
_recipient,
_token,
symbol,
_amount
);
}
/*
* @dev: Unlocks Chain33 and ERC20 tokens held on the contract.
*
* @param _recipient: recipient's Chain33 address
* @param _token: token contract address
* @param _symbol: token symbol
* @param _amount: wei amount or ERC20 token count
\ */
function unlock(
address payable _recipient,
address _token,
string memory _symbol,
uint256 _amount
)
public
onlyGoAssetBridge
hasLockedFunds(
_token,
_amount
)
canDeliver(
_token,
_amount
)
{
unlockFunds(
_recipient,
_token,
_symbol,
_amount
);
}
/*
* @dev: Exposes an item's current status.
*
* @param _id: The item in question.
* @return: Boolean indicating the lock status.
*/
function getGoAssetDepositStatus(
bytes32 _id
)
public
view
returns(bool)
{
return isLockedGoAssetDeposit(_id);
}
/*
* @dev: Allows access to a GoAsset deposit's information via its unique identifier.
*
* @param _id: The deposit to be viewed.
* @return: Original sender's Chain33 address.
* @return: Intended GoAsset recipient's address in bytes.
* @return: The lock deposit's currency, denoted by a token address.
* @return: The amount locked in the deposit.
* @return: The deposit's unique nonce.
*/
function viewGoAssetDeposit(
bytes32 _id
)
public
view
returns(address, address payable, address, uint256)
{
return getGoAssetDeposit(_id);
}
}
\ No newline at end of file
pragma solidity ^0.5.0;
import "../../openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";
import "../../openzeppelin-solidity/contracts/token/ERC20/ERC20Burnable.sol";
import "../../openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
/**
* @title BridgeToken
* @dev Mintable, ERC20 compatible BankToken for use by BridgeBank
**/
contract BridgeToken is ERC20Mintable, ERC20Burnable, ERC20Detailed {
constructor(
string memory _symbol
)
public
ERC20Detailed(
_symbol,
_symbol,
8
)
{
// Intentionally left blank
}
}
\ No newline at end of file
pragma solidity ^0.5.0;
import "../../openzeppelin-solidity/contracts/math/SafeMath.sol";
import "./BridgeToken.sol";
/*
* @title: EvmAssetBank
* @dev: EvmAsset bank which locks Chain33/ERC20 token deposits, and unlocks
* Chain33/ERC20 tokens once the prophecy has been successfully processed.
* @dev:当emv资产转移到go合约时,用于锁定资产;
* 当emv资产从go合约进行提币时,用于解锁资产;
*/
contract EvmAssetBank {
using SafeMath for uint256;
address payable public offlineSave;
uint256 public lockNonce;
mapping(address => uint256) public lockedFunds;
mapping(bytes32 => address) public tokenAllow2Lock;
mapping(address => OfflineSaveCfg) public offlineSaveCfgs;
uint8 public lowThreshold = 5;
uint8 public highThreshold = 80;
struct OfflineSaveCfg {
address token;
string symbol;
uint256 _threshold;
uint8 _percents;
}
/*
* @dev: Event declarations
*/
event LogLock(
address _from,
address _to,
address _token,
string _symbol,
uint256 _value,
uint256 _nonce
);
event LogUnlock(
address _to,
address _token,
string _symbol,
uint256 _value
);
/*
* @dev: Modifier declarations
*/
modifier hasLockedFunds(
address _token,
uint256 _amount
) {
require(
lockedFunds[_token] >= _amount,
"The Bank does not hold enough locked tokens to fulfill this request."
);
_;
}
modifier canDeliver(
address _token,
uint256 _amount
)
{
if(_token == address(0)) {
require(
address(this).balance >= _amount,
'Insufficient Chain33 balance for delivery.'
);
} else {
require(
BridgeToken(_token).balanceOf(address(this)) >= _amount,
'Insufficient ERC20 token balance for delivery.'
);
}
_;
}
modifier availableNonce() {
require(
lockNonce + 1 > lockNonce,
'No available nonces.'
);
_;
}
/*
* @dev: Constructor which sets the lock nonce
*/
constructor()
public
{
lockNonce = 0;
}
/*
* @dev: addToken2AllowLock used to add token with the specified address to be
* allowed locked from GoAsset
*
* @param _token: token contract address
* @param _symbol: token symbol
*/
function addToken2AllowLock(
address _token,
string memory _symbol
)
internal
{
bytes32 symHash = keccak256(abi.encodePacked(_symbol));
address tokenQuery = tokenAllow2Lock[symHash];
require(tokenQuery == address(0), 'The token with the same symbol has been added to lock allow list already.');
tokenAllow2Lock[symHash] = _token;
}
/*
* @dev: addToken2AllowLock used to add token with the specified address to be
* allowed locked from GoAsset
*
* @param _symbol: token symbol
*/
function getLockedTokenAddress(string memory _symbol) public view returns(address)
{
bytes32 symHash = keccak256(abi.encodePacked(_symbol));
return tokenAllow2Lock[symHash];
}
/*
* @dev: configOfflineSave4Lock used to config threshold to trigger tranfer token to offline account
* when the balance of locked token reaches
*
* @param _token: token contract address
* @param _symbol:token symbol,just used for double check that token address and symbol is consistent
* @param _threshold: _threshold to trigger transfer
* @param _percents: amount to transfer per percents of threshold
*/
function configOfflineSave4Lock(
address _token,
string memory _symbol,
uint256 _threshold,
uint8 _percents
)
internal
{
require(
_percents >= lowThreshold && _percents <= highThreshold,
"The percents to trigger should within range [5, 80]"
);
OfflineSaveCfg memory offlineSaveCfg = OfflineSaveCfg(
_token,
_symbol,
_threshold,
_percents
);
offlineSaveCfgs[_token] = offlineSaveCfg;
}
/*
* @dev: getofflineSaveCfg used to get token's offline save configuration
*
* @param _token: token contract address
*/
function getofflineSaveCfg(address _token) public view returns(uint256, uint8)
{
OfflineSaveCfg memory offlineSaveCfg = offlineSaveCfgs[_token];
return (offlineSaveCfg._threshold, offlineSaveCfg._percents);
}
/*
* @dev: Creates a new Chain33 deposit with a unique id.
*
* @param _sender: The sender's Chain33 address.
* @param _recipient: The intended recipient's Chain33 address.
* @param _token: The currency type, either erc20 or Chain33.
* @param _amount: The amount of erc20 tokens/ Chain33 (in wei) to be itemized.
*/
function lockFunds(
address payable _sender,
address _recipient,
address _token,
string memory _symbol,
uint256 _amount
)
internal
{
// Incerment the lock nonce
lockNonce = lockNonce.add(1);
// Increment locked funds by the amount of tokens to be locked
lockedFunds[_token] = lockedFunds[_token].add(_amount);
emit LogLock(
_sender,
_recipient,
_token,
_symbol,
_amount,
lockNonce
);
if (address(0) == offlineSave) {
return;
}
uint256 balance;
if (address(0) == _token) {
balance = address(this).balance;
} else {
balance = BridgeToken(_token).balanceOf(address(this));
}
OfflineSaveCfg memory offlineSaveCfg = offlineSaveCfgs[_token];
//check not zero,so configured already
if (offlineSaveCfg._percents < lowThreshold) {
return;
}
if (balance < offlineSaveCfg._threshold ) {
return;
}
uint256 amount = offlineSaveCfg._percents * balance / 100;
if (address(0) == _token) {
offlineSave.transfer(amount);
} else {
require(BridgeToken(_token).transfer(offlineSave, amount), "Erc20 Token Transfer to offline Save account failed");
}
}
/*
* @dev: Unlocks funds held on contract and sends them to the
* intended recipient
*
* @param _recipient: recipient's Chain33 address
* @param _token: token contract address
* @param _symbol: token symbol
* @param _amount: wei amount or ERC20 token count
*/
function unlockFunds(
address payable _recipient,
address _token,
string memory _symbol,
uint256 _amount
)
internal
{
// Decrement locked funds mapping by the amount of tokens to be unlocked
lockedFunds[_token] = lockedFunds[_token].sub(_amount);
// Transfer funds to intended recipient
if (_token == address(0)) {
_recipient.transfer(_amount);
} else {
require(
BridgeToken(_token).transfer(_recipient, _amount),
"Token transfer failed"
);
}
emit LogUnlock(
_recipient,
_token,
_symbol,
_amount
);
}
}
pragma solidity ^0.5.0;
import "../../openzeppelin-solidity/contracts/math/SafeMath.sol";
import "./BridgeToken.sol";
/**
* @title GoAssetBank
* @dev Manages the deployment and minting of ERC20 compatible BridgeTokens
* which represent assets issued by Go contracts.
* @dev 为chain33上的go合约发行的资产进行BridgeTokens合约部署,铸币和销毁
**/
contract GoAssetBank {
using SafeMath for uint256;
uint256 public bridgeTokenCount;
mapping(address => bool) public bridgeTokenWhitelist;
mapping(bytes32 => bool) public bridgeTokenCreated;
mapping(bytes32 => GoAssetDeposit) goAssetDeposits;
mapping(bytes32 => GoAssetBurn) goAssetBurns;
mapping(address => DepositBurnCount) depositBurnCounts;
mapping(bytes32 => address) public token2address;
struct GoAssetDeposit {
address goAssetSender;
address payable chain33Recipient;
address bridgeTokenAddress;
uint256 amount;
bool exist;
uint256 nonce;
}
struct DepositBurnCount {
uint256 depositCount;
uint256 burnCount;
}
struct GoAssetBurn {
address goAssetSender;
address payable chain33Owner;
address bridgeTokenAddress;
uint256 amount;
uint256 nonce;
}
/*
* @dev: Event declarations
*/
event LogNewBridgeToken(
address _token,
string _symbol
);
event LogBridgeTokenMint(
address _token,
string _symbol,
uint256 _amount,
address _beneficiary
);
event LogGoAssetTokenBurn(
address _token,
string _symbol,
uint256 _amount,
address _ownerFrom,
address _goAssetReceiver,
uint256 _nonce
);
/*
* @dev: Modifier to make sure this symbol not created now
*/
modifier notCreated(string memory _symbol)
{
require(
!hasBridgeTokenCreated(_symbol),
"The symbol has been created already"
);
_;
}
/*
* @dev: Modifier to make sure this symbol not created now
*/
modifier created(string memory _symbol)
{
require(
hasBridgeTokenCreated(_symbol),
"The symbol has not been created yet"
);
_;
}
/*
* @dev: Constructor, sets bridgeTokenCount
*/
constructor () public {
bridgeTokenCount = 0;
}
/*
* @dev: check whether this symbol has been created yet or not
*
* @param _symbol: token symbol
* @return: true or false
*/
function hasBridgeTokenCreated(string memory _symbol) public view returns(bool) {
bytes32 symHash = keccak256(abi.encodePacked(_symbol));
return bridgeTokenCreated[symHash];
}
/*
* @dev: Creates a new GoAssetDeposit with a unique ID
*
* @param _goAssetSender: The _goAssetSender sender's address.
* @param _chain33Recipient: The intended recipient's Chain33 address.
* @param _token: The currency type
* @param _amount: The amount in the deposit.
* @return: The newly created GoAssetSenderDeposit's unique id.
*/
function newGoAssetDeposit(
address _goAssetSender,
address payable _chain33Recipient,
address _token,
uint256 _amount
)
internal
returns(bytes32)
{
DepositBurnCount memory depositBurnCount = depositBurnCounts[_token];
depositBurnCount.depositCount = depositBurnCount.depositCount.add(1);
depositBurnCounts[_token] = depositBurnCount;
bytes32 depositID = keccak256(
abi.encodePacked(
_goAssetSender,
_chain33Recipient,
_token,
_amount,
depositBurnCount.depositCount
)
);
goAssetDeposits[depositID] = GoAssetDeposit(
_goAssetSender,
_chain33Recipient,
_token,
_amount,
true,
depositBurnCount.depositCount
);
return depositID;
}
/*
* @dev: Creates a new GoAssetBurn with a unique ID
*
* @param _goAssetSender: The go Asset Sender address
* @param _chain33Owner: The owner's Chain33 address.
* @param _token: The token Address
* @param _amount: The amount to be burned.
* @param _nonce: The nonce indicates the burn count for this token
* @return: The newly created GoAssetBurn's unique id.
*/
function newGoAssetBurn(
address _goAssetSender,
address payable _chain33Owner,
address _token,
uint256 _amount,
uint256 nonce
)
internal
returns(bytes32)
{
bytes32 burnID = keccak256(
abi.encodePacked(
_goAssetSender,
_chain33Owner,
_token,
_amount,
nonce
)
);
goAssetBurns[burnID] = GoAssetBurn(
_goAssetSender,
_chain33Owner,
_token,
_amount,
nonce
);
return burnID;
}
/*
* @dev: Deploys a new BridgeToken contract
*
* @param _symbol: The BridgeToken's symbol
*/
function deployNewBridgeToken(
string memory _symbol
)
internal
notCreated(_symbol)
returns(address)
{
bridgeTokenCount = bridgeTokenCount.add(1);
// Deploy new bridge token contract
BridgeToken newBridgeToken = (new BridgeToken)(_symbol);
// Set address in tokens mapping
address newBridgeTokenAddress = address(newBridgeToken);
bridgeTokenWhitelist[newBridgeTokenAddress] = true;
bytes32 symHash = keccak256(abi.encodePacked(_symbol));
bridgeTokenCreated[symHash] = true;
depositBurnCounts[newBridgeTokenAddress] = DepositBurnCount(
uint256(0),
uint256(0));
token2address[symHash] = newBridgeTokenAddress;
emit LogNewBridgeToken(
newBridgeTokenAddress,
_symbol
);
return newBridgeTokenAddress;
}
/*
* @dev: Mints new goAsset tokens
*
* @param _goAssetSender: The _goAssetSender sender's address.
* @param _chain33Recipient: The intended recipient's Chain33 address.
* @param _goAssetTokenAddress: The currency type
* @param _symbol: goAsset token symbol
* @param _amount: number of goAsset tokens to be minted
*/
function mintNewBridgeTokens(
address _goAssetSender,
address payable _intendedRecipient,
address _bridgeTokenAddress,
string memory _symbol,
uint256 _amount
)
internal
{
// Must be whitelisted bridge token
require(
bridgeTokenWhitelist[_bridgeTokenAddress],
"Token must be a whitelisted bridge token"
);
// Mint bridge tokens
require(
BridgeToken(_bridgeTokenAddress).mint(
_intendedRecipient,
_amount
),
"Attempted mint of bridge tokens failed"
);
newGoAssetDeposit(
_goAssetSender,
_intendedRecipient,
_bridgeTokenAddress,
_amount
);
emit LogBridgeTokenMint(
_bridgeTokenAddress,
_symbol,
_amount,
_intendedRecipient
);
}
/*
* @dev: Burn goAsset tokens
*
* @param _from: The address to be burned from
* @param _goAssetReceiver: The receiver's GoAsset address in bytes.
* @param _goAssetTokenAddress: The token address of goAsset asset issued on chain33
* @param _amount: number of goAsset tokens to be minted
*/
function burnGoAssetTokens(
address payable _from,
address _goAssetReceiver,
address _goAssetTokenAddress,
uint256 _amount
)
internal
{
// Must be whitelisted bridge token
require(
bridgeTokenWhitelist[_goAssetTokenAddress],
"Token must be a whitelisted bridge token"
);
// burn bridge tokens
BridgeToken bridgeTokenInstance = BridgeToken(_goAssetTokenAddress);
bridgeTokenInstance.burnFrom(_from, _amount);
DepositBurnCount memory depositBurnCount = depositBurnCounts[_goAssetTokenAddress];
require(
depositBurnCount.burnCount + 1 > depositBurnCount.burnCount,
"burn nonce is not available"
);
depositBurnCount.burnCount = depositBurnCount.burnCount.add(1);
depositBurnCounts[_goAssetTokenAddress] = depositBurnCount;
newGoAssetBurn(
_goAssetReceiver,
_from,
_goAssetTokenAddress,
_amount,
depositBurnCount.burnCount
);
emit LogGoAssetTokenBurn(
_goAssetTokenAddress,
bridgeTokenInstance.symbol(),
_amount,
_from,
_goAssetReceiver,
depositBurnCount.burnCount
);
}
/*
* @dev: Checks if an individual GoAssetDeposit exists.
*
* @param _id: The unique GoAssetDeposit's id.
* @return: Boolean indicating if the GoAssetDeposit exists in memory.
*/
function isLockedGoAssetDeposit(
bytes32 _id
)
internal
view
returns(bool)
{
return(goAssetDeposits[_id].exist);
}
/*
* @dev: Gets an item's information
*
* @param _Id: The item containing the desired information.
* @return: Sender's address.
* @return: Recipient's address in bytes.
* @return: Token address.
* @return: Amount of chain33/erc20 in the item.
* @return: Unique nonce of the item.
*/
function getGoAssetDeposit(
bytes32 _id
)
internal
view
returns(address, address payable, address, uint256)
{
GoAssetDeposit memory deposit = goAssetDeposits[_id];
return(
deposit.goAssetSender,
deposit.chain33Recipient,
deposit.bridgeTokenAddress,
deposit.amount
);
}
function getToken2address(string memory _symbol)
created(_symbol)
public view returns(address)
{
bytes32 symHash = keccak256(abi.encodePacked(_symbol));
return token2address[symHash];
}
}
\ No newline at end of file
pragma solidity ^0.5.0;
contract BridgeRegistry {
address public goAssetBridge;
address public bridgeBank;
address public oracle;
address public valset;
uint256 public deployHeight;
event LogContractsRegistered(
address _goAssetBridge,
address _bridgeBank,
address _oracle,
address _valset
);
constructor(
address _goAssetBridge,
address _bridgeBank,
address _oracle,
address _valset
)
public
{
goAssetBridge = _goAssetBridge;
bridgeBank = _bridgeBank;
oracle = _oracle;
valset = _valset;
deployHeight = block.number;
emit LogContractsRegistered(
goAssetBridge,
bridgeBank,
oracle,
valset
);
}
}
\ No newline at end of file
pragma solidity ^0.5.0;
import "../openzeppelin-solidity/contracts/math/SafeMath.sol";
import "./Valset.sol";
import "./BridgeBank/BridgeBank.sol";
contract GoAssetBridge {
using SafeMath for uint256;
/*
* @dev: Public variable declarations
*/
address public operator;
Valset public valset;
address public oracle;
bool public hasOracle;
BridgeBank public bridgeBank;
bool public hasBridgeBank;
uint256 public prophecyClaimCount;
mapping(bytes32 => ProphecyClaim) public prophecyClaims;
enum Status {
Null,
Pending,
Success,
Failed
}
enum ClaimType {
Unsupported,
Burn,
Lock
}
struct ProphecyClaim {
ClaimType claimType;
address goAssetSender;
address payable chain33Receiver;
address originalValidator;
address tokenAddress;
string symbol;
uint256 amount;
Status status;
}
/*
* @dev: Event declarations
*/
event LogOracleSet(
address _oracle
);
event LogBridgeBankSet(
address _bridgeBank
);
event LogNewProphecyClaim(
uint256 _prophecyID,
ClaimType _claimType,
address _goAssetSender,
address payable _chain33Receiver,
address _validatorAddress,
address _tokenAddress,
string _symbol,
uint256 _amount
);
event LogProphecyCompleted(
bytes32 _claimID,
ClaimType _claimType
);
/*
* @dev: Modifier which only allows access to currently pending prophecies
*/
modifier isPending(
bytes32 _claimID
)
{
require(
isProphecyClaimActive(_claimID),
"Prophecy claim is not active"
);
_;
}
/*
* @dev: Modifier to restrict access to the operator.
*/
modifier onlyOperator()
{
require(
msg.sender == operator,
'Must be the operator.'
);
_;
}
/*
* @dev: Modifier to restrict access to the oracle.
*/
modifier onlyOracle()
{
require(
msg.sender == oracle,
'Must be the oracle.'
);
_;
}
/*
* @dev: The bridge is not active until oracle and bridge bank are set
*/
modifier isActive()
{
require(
hasOracle == true && hasBridgeBank == true,
"The Operator must set the oracle and bridge bank for bridge activation"
);
_;
}
/*
* @dev: Modifier to make sure the claim type is valid
*/
modifier validClaimType(
ClaimType _claimType
)
{
require(
_claimType == ClaimType.Burn || _claimType == ClaimType.Lock,
"The claim type must be ClaimType.Burn or ClaimType.Lock"
);
_;
}
/*
* @dev: Constructor
*/
constructor(
address _operator,
address _valset
)
public
{
prophecyClaimCount = 0;
operator = _operator;
valset = Valset(_valset);
hasOracle = false;
hasBridgeBank = false;
}
/*
* @dev: setOracle
*/
function setOracle(
address _oracle
)
public
onlyOperator
{
require(
!hasOracle,
"The Oracle cannot be updated once it has been set"
);
hasOracle = true;
oracle = _oracle;
emit LogOracleSet(
oracle
);
}
/*
* @dev: setBridgeBank
*/
function setBridgeBank(
address payable _bridgeBank
)
public
onlyOperator
{
require(
!hasBridgeBank,
"The Bridge Bank cannot be updated once it has been set"
);
hasBridgeBank = true;
bridgeBank = BridgeBank(_bridgeBank);
emit LogBridgeBankSet(
address(bridgeBank)
);
}
/*
* @dev: setNewProphecyClaim
* Sets a new burn or lock prophecy claim, adding it to the prophecyClaims mapping.
* Lock claims can only be created for BridgeTokens on BridgeBank's whitelist. The operator
* is responsible for adding them, and lock claims will fail until the operator has done so.
*/
function setNewProphecyClaim(
bytes32 _claimID,
uint8 _claimType,
address _goAssetSender,
address payable _chain33Receiver,
address _originalValidator,
address _tokenAddress,
string memory _symbol,
uint256 _amount
)
public
isActive
onlyOracle
{
// Increment the prophecy claim count
prophecyClaimCount = prophecyClaimCount.add(1);
ClaimType claimType = ClaimType(_claimType);
//overwrite the token address in case of lock
if (claimType == ClaimType.Lock) {
_tokenAddress = bridgeBank.getToken2address(_symbol);
}
// Create the new ProphecyClaim
ProphecyClaim memory prophecyClaim = ProphecyClaim(
claimType,
_goAssetSender,
_chain33Receiver,
_originalValidator,
_tokenAddress,
_symbol,
_amount,
Status.Pending
);
// Add the new ProphecyClaim to the mapping
prophecyClaims[_claimID] = prophecyClaim;
emit LogNewProphecyClaim(
prophecyClaimCount,
claimType,
_goAssetSender,
_chain33Receiver,
_originalValidator,
_tokenAddress,
_symbol,
_amount
);
}
/*
* @dev: completeClaim
* Allows for the completion of ProphecyClaims once processed by the Oracle.
* Burn claims unlock tokens stored by BridgeBank.
* Lock claims mint BridgeTokens on BridgeBank's token whitelist.
*/
function completeClaim(
bytes32 _claimID
)
public
isPending(_claimID)
{
require(
msg.sender == oracle,
"Only the Oracle may complete prophecies"
);
prophecyClaims[_claimID].status = Status.Success;
ClaimType claimType = prophecyClaims[_claimID].claimType;
if(claimType == ClaimType.Burn) {
unlockTokens(_claimID);
} else {
issueBridgeTokens(_claimID);
}
emit LogProphecyCompleted(
_claimID,
claimType
);
}
/*
* @dev: issueBridgeTokens
* Issues a request for the BridgeBank to mint new BridgeTokens
*/
function issueBridgeTokens(
bytes32 _claimID
)
internal
{
ProphecyClaim memory prophecyClaim = prophecyClaims[_claimID];
bridgeBank.mintBridgeTokens(
prophecyClaim.goAssetSender,
prophecyClaim.chain33Receiver,
prophecyClaim.tokenAddress,
prophecyClaim.symbol,
prophecyClaim.amount
);
}
/*
* @dev: unlockTokens
* Issues a request for the BridgeBank to unlock funds held on contract
*/
function unlockTokens(
bytes32 _claimID
)
internal
{
ProphecyClaim memory prophecyClaim = prophecyClaims[_claimID];
bridgeBank.unlock(
prophecyClaim.chain33Receiver,
prophecyClaim.tokenAddress,
prophecyClaim.symbol,
prophecyClaim.amount
);
}
/*
* @dev: isProphecyClaimActive
* Returns boolean indicating if the ProphecyClaim is active
*/
function isProphecyClaimActive(
bytes32 _claimID
)
public
view
returns(bool)
{
return prophecyClaims[_claimID].status == Status.Pending;
}
/*
* @dev: isProphecyValidatorActive
* Returns boolean indicating if the validator that originally
* submitted the ProphecyClaim is still an active validator
*/
function isProphecyClaimValidatorActive(
bytes32 _claimID
)
public
view
returns(bool)
{
return valset.isActiveValidator(
prophecyClaims[_claimID].originalValidator
);
}
/*
* @dev: Modifier to make sure the claim type is valid
*/
function isValidClaimType(uint8 _claimType) public pure returns(bool)
{
ClaimType claimType = ClaimType(_claimType);
if (claimType == ClaimType.Burn || claimType == ClaimType.Lock) {
return true;
}
return false;
}
}
##solc 使用版本为:Version: 0.5.16
##编译solidity,并产生bin文件,abi文件,和相应的go文件
SRC_CONTRACT0 := .
GO_OUT0 := ${SRC_CONTRACT0}/generated
PACKAGE := generated
proj := "build"
.PHONY: default build clean registry bridgeBank
default: depends build
build: depends
@abigen --sol $(SRC_CONTRACT0)/BridgeRegistry.sol --pkg $(PACKAGE) --out $(GO_OUT0)/BridgeRegistry.go
@abigen --sol $(SRC_CONTRACT0)/BridgeBank/BridgeBank.sol --pkg $(PACKAGE) --out $(GO_OUT0)/BridgeBank.go
clean:
@rm -fr $(GO_OUT)/*
registry0:
@abigen --sol $(SRC_CONTRACT0)/BridgeRegistry.sol --pkg $(PACKAGE) --out $(GO_OUT0)/BridgeRegistry.go
bridgeBank0:
@abigen --sol $(SRC_CONTRACT0)/BridgeBank/BridgeBank.sol --pkg $(PACKAGE) --out $(GO_OUT0)/BridgeBank.go
asmExample:
@solc --asm --bin -o tmp/ valset-bin=./tmp/valset-bin Valset.sol
depends:
if ! [ -d openzeppelin-solidity ]; then \
echo "not exist openzeppelin-solidity and going to get" ; \
go get github.com/OpenZeppelin/openzeppelin-contracts@v2.5 ; \
mkdir openzeppelin-solidity ;\
cp -r ${GOPATH}/pkg/mod/github.com/\!open\!zeppelin/openzeppelin-contracts@v2.5.0+incompatible/contracts openzeppelin-solidity ; \
fi; \
pragma solidity ^0.5.0;
import "../openzeppelin-solidity/contracts/math/SafeMath.sol";
import "./Valset.sol";
import "./GoAssetBridge.sol";
contract Oracle {
using SafeMath for uint256;
/*
* @dev: Public variable declarations
*/
GoAssetBridge public goAssetBridge;
Valset public valset;
address public operator;
// Tracks the number of OracleClaims made on an individual BridgeClaim
mapping(bytes32 => address[]) public oracleClaimValidators;
mapping(bytes32 => mapping(address => bool)) public hasMadeClaim;
enum ClaimType {
Unsupported,
Burn,
Lock
}
/*
* @dev: Event declarations
*/
event LogNewOracleClaim(
bytes32 _claimID,
address _validatorAddress,
bytes _signature
);
event LogProphecyProcessed(
bytes32 _claimID,
uint256 _weightedSignedPower,
uint256 _weightedTotalPower,
address _submitter
);
/*
* @dev: Modifier to restrict access to the operator.
*/
modifier onlyOperator()
{
require(
msg.sender == operator,
'Must be the operator.'
);
_;
}
/*
* @dev: Modifier to restrict access to current ValSet validators
*/
modifier onlyValidator()
{
require(
valset.isActiveValidator(msg.sender),
"Must be an active validator"
);
_;
}
/*
* @dev: Modifier to restrict access to current ValSet validators
*/
modifier isPending(
bytes32 _claimID
)
{
require(
goAssetBridge.isProphecyClaimActive(
_claimID
) == true,
"The prophecy must be pending for this operation"
);
_;
}
/*
* @dev: Modifier to restrict the claim type must be burn or lock
*/
modifier isValidClaimType(
ClaimType _claimType
)
{
require(
goAssetBridge.isValidClaimType(
uint8(_claimType)
) == true,
"The claim type must be burn or lock"
);
_;
}
/*
* @dev: Constructor
*/
constructor(
address _operator,
address _valset,
address _goAssetBridge
)
public
{
operator = _operator;
goAssetBridge = GoAssetBridge(_goAssetBridge);
valset = Valset(_valset);
}
/*
* @dev: newOracleClaim
* Allows validators to make new OracleClaims on goAsset lock/burn prophecy,
* if the required vote power reached,just make it processed
* @param _claimType: burn or lock,
* @param _goAssetSender: goAsset sender,
* @param _chain33Receiver: receiver on chain33
* @param _tokenAddress: token address
* @param _symbol: token symbol
* @param _amount: amount
* @param _claimID: claim id
* @param _message: message for verifying
* @param _signature: need to recover sender
*/
function newOracleClaim(
ClaimType _claimType,
address _goAssetSender,
address payable _chain33Receiver,
address _tokenAddress,
string memory _symbol,
uint256 _amount,
bytes32 _claimID,
bytes memory _signature
)
public
onlyValidator
isValidClaimType(_claimType)
{
address validatorAddress = msg.sender;
// Validate the msg.sender's signature
require(
validatorAddress == valset.recover(
_claimID,
_signature
),
"Invalid _claimID signature."
);
// Confirm that this address has not already made an oracle claim on this _ClaimID
require(
!hasMadeClaim[_claimID][validatorAddress],
"Cannot make duplicate oracle claims from the same address."
);
if (oracleClaimValidators[_claimID].length == 0) {
goAssetBridge.setNewProphecyClaim(
_claimID,
uint8(_claimType),
_goAssetSender,
_chain33Receiver,
validatorAddress,
_tokenAddress,
_symbol,
_amount);
}
hasMadeClaim[_claimID][validatorAddress] = true;
oracleClaimValidators[_claimID].push(validatorAddress);
emit LogNewOracleClaim(
_claimID,
validatorAddress,
_signature
);
(bool valid, uint256 weightedSignedPower, uint256 weightedTotalPower ) = getClaimThreshold(_claimID);
if (true == valid) {
//if processed already,just emit an event
if (goAssetBridge.isProphecyClaimActive(_claimID) == true) {
completeClaim(_claimID);
}
emit LogProphecyProcessed(
_claimID,
weightedSignedPower,
weightedTotalPower,
msg.sender
);
}
}
/*
* @dev: checkBridgeProphecy
* Operator accessor method which checks if a prophecy has passed
* the validity threshold, without actually completing the prophecy.
*/
function checkBridgeProphecy(
bytes32 _claimID
)
public
view
onlyOperator
isPending(_claimID)
returns(bool, uint256, uint256)
{
require(
goAssetBridge.isProphecyClaimActive(
_claimID
) == true,
"Can only check active prophecies"
);
return getClaimThreshold(
_claimID
);
}
/*
* @dev: getClaimThreshold
* Calculates the status of a claim. The claim is considered valid if the
* combined active signatory validator powers pass the validation threshold.
* The hardcoded threshold is (Combined signed power * 2) >= (Total power * 3).
*/
function getClaimThreshold(
bytes32 _claimID
)
internal
view
returns(bool, uint256, uint256)
{
uint256 signedPower = 0;
uint256 totalPower = valset.totalPower();
// Iterate over the signatory addresses
for (uint256 i = 0; i < oracleClaimValidators[_claimID].length; i = i.add(1)) {
address signer = oracleClaimValidators[_claimID][i];
// Only add the power of active validators
if(valset.isActiveValidator(signer)) {
signedPower = signedPower.add(
valset.getValidatorPower(
signer
)
);
}
}
// Calculate if weighted signed power has reached threshold of weighted total power
uint256 weightedSignedPower = signedPower.mul(3);
uint256 weightedTotalPower = totalPower.mul(2);
bool hasReachedThreshold = weightedSignedPower >= weightedTotalPower;
return(
hasReachedThreshold,
weightedSignedPower,
weightedTotalPower
);
}
/*
* @dev: completeClaim
* Completes a claim by completing the corresponding BridgeClaim
* on the GoAssetBridge.
*/
function completeClaim(
bytes32 _claimID
)
internal
{
goAssetBridge.completeClaim(
_claimID
);
}
}
\ No newline at end of file
pragma solidity ^0.5.0;
import "../openzeppelin-solidity/contracts/math/SafeMath.sol";
import "../openzeppelin-solidity/contracts/cryptography/ECDSA.sol";
contract Valset {
using SafeMath for uint256;
using ECDSA for bytes32;
/*
* @dev: Variable declarations
*/
address public operator;
uint256 public totalPower;
uint256 public currentValsetVersion;
uint256 public validatorCount;
mapping (bytes32 => bool) public validators;
mapping(bytes32 => uint256) public powers;
/*
* @dev: Event declarations
*/
event LogValidatorAdded(
address _validator,
uint256 _power,
uint256 _currentValsetVersion,
uint256 _validatorCount,
uint256 _totalPower
);
event LogValidatorPowerUpdated(
address _validator,
uint256 _power,
uint256 _currentValsetVersion,
uint256 _validatorCount,
uint256 _totalPower
);
event LogValidatorRemoved(
address _validator,
uint256 _power,
uint256 _currentValsetVersion,
uint256 _validatorCount,
uint256 _totalPower
);
event LogValsetReset(
uint256 _newValsetVersion,
uint256 _validatorCount,
uint256 _totalPower
);
event LogValsetUpdated(
uint256 _newValsetVersion,
uint256 _validatorCount,
uint256 _totalPower
);
/*
* @dev: Modifier which restricts access to the operator.
*/
modifier onlyOperator()
{
require(
msg.sender == operator,
'Must be the operator.'
);
_;
}
/*
* @dev: Constructor
*/
constructor(
address _operator,
address[] memory _initValidators,
uint256[] memory _initPowers
)
public
{
operator = _operator;
currentValsetVersion = 0;
updateValset(
_initValidators,
_initPowers
);
}
function recover(
bytes32 _message,
bytes memory _signature
)
public
pure
returns (address)
{
bytes32 message = ethMessageHash(_message);
return verify(message, _signature);
}
/*
* @dev: addValidator
*/
function addValidator(
address _validatorAddress,
uint256 _validatorPower
)
public
onlyOperator
{
addValidatorInternal(
_validatorAddress,
_validatorPower
);
}
/*
* @dev: updateValidatorPower
*/
function updateValidatorPower(
address _validatorAddress,
uint256 _newValidatorPower
)
public
onlyOperator
{
// Create a unique key which for this validator's position in the current version of the mapping
bytes32 key = keccak256(
abi.encodePacked(
currentValsetVersion,
_validatorAddress
)
);
require(
validators[key],
"Can only update the power of active valdiators"
);
// Adjust total power by new validator power
uint256 priorPower = powers[key];
totalPower = totalPower.sub(priorPower);
totalPower = totalPower.add(_newValidatorPower);
// Set validator's new power
powers[key] = _newValidatorPower;
emit LogValidatorPowerUpdated(
_validatorAddress,
_newValidatorPower,
currentValsetVersion,
validatorCount,
totalPower
);
}
/*
* @dev: removeValidator
*/
function removeValidator(
address _validatorAddress
)
public
onlyOperator
{
// Create a unique key which for this validator's position in the current version of the mapping
bytes32 key = keccak256(
abi.encodePacked(
currentValsetVersion,
_validatorAddress
)
);
require(
validators[key],
"Can only remove active valdiators"
);
// Update validator count and total power
validatorCount = validatorCount.sub(1);
totalPower = totalPower.sub(powers[key]);
// Delete validator and power
delete validators[key];
delete powers[key];
emit LogValidatorRemoved(
_validatorAddress,
0,
currentValsetVersion,
validatorCount,
totalPower
);
}
/*
* @dev: updateValset
*/
function updateValset(
address[] memory _validators,
uint256[] memory _powers
)
public
onlyOperator
{
require(
_validators.length == _powers.length,
"Every validator must have a corresponding power"
);
resetValset();
for(uint256 i = 0; i < _validators.length; i = i.add(1)) {
addValidatorInternal(_validators[i], _powers[i]);
}
emit LogValsetUpdated(
currentValsetVersion,
validatorCount,
totalPower
);
}
/*
* @dev: isActiveValidator
*/
function isActiveValidator(
address _validatorAddress
)
public
view
returns(bool)
{
// Recreate the unique key for this address given the current mapping version
bytes32 key = keccak256(
abi.encodePacked(
currentValsetVersion,
_validatorAddress
)
);
// Return bool indicating if this address is an active validator
return validators[key];
}
/*
* @dev: getValidatorPower
*/
function getValidatorPower(
address _validatorAddress
)
external
view
returns(uint256)
{
// Recreate the unique key for this address given the current mapping version
bytes32 key = keccak256(
abi.encodePacked(
currentValsetVersion,
_validatorAddress
)
);
return powers[key];
}
/*
* @dev: recoverGas
*/
function recoverGas(
uint256 _valsetVersion,
address _validatorAddress
)
external
onlyOperator
{
require(
_valsetVersion < currentValsetVersion,
"Gas recovery only allowed for previous validator sets"
);
// Recreate the unique key used to identify this validator in the given version
bytes32 key = keccak256(
abi.encodePacked(
_valsetVersion,
_validatorAddress
)
);
// Delete from mappings and recover gas
delete(validators[key]);
delete(powers[key]);
}
/*
* @dev: addValidatorInternal
*/
function addValidatorInternal(
address _validatorAddress,
uint256 _validatorPower
)
internal
{
// Create a unique key which for this validator's position in the current version of the mapping
bytes32 key = keccak256(
abi.encodePacked(
currentValsetVersion,
_validatorAddress
)
);
validatorCount = validatorCount.add(1);
totalPower = totalPower.add(_validatorPower);
// Set validator as active and set their power
validators[key] = true;
powers[key] = _validatorPower;
emit LogValidatorAdded(
_validatorAddress,
_validatorPower,
currentValsetVersion,
validatorCount,
totalPower
);
}
/*
* @dev: resetValset
*/
function resetValset()
internal
{
currentValsetVersion = currentValsetVersion.add(1);
validatorCount = 0;
totalPower = 0;
emit LogValsetReset(
currentValsetVersion,
validatorCount,
totalPower
);
}
/*
* @dev: Verify
*
*/
function verify(
bytes32 h,
bytes memory signature
)
internal
pure
returns (address)
{
bytes32 r;
bytes32 s;
uint8 v;
// Check the signature length
if (signature.length != 65) {
return (address(0));
}
// Divide the signature in r, s and v variables
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
// solium-disable-next-line security/no-inline-assembly
assembly {
r := mload(add(signature, 32))
s := mload(add(signature, 64))
v := byte(0, mload(add(signature, 96)))
}
// Version of signature should be 27 or 28, but 0 and 1 are also possible versions
if (v < 27) {
v += 27;
}
// If the version is correct return the signer address
if (v != 27 && v != 28) {
return (address(0));
} else {
// solium-disable-next-line arg-overflow
return ecrecover(h, v, r, s);
}
}
/**
* @dev prefix a bytes32 value with "\x19Ethereum Signed Message:" and hash the result
*/
function ethMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev debug for pack
*/
function Debug_Packed(bytes32 hash) public pure returns (bytes memory) {
bytes memory info;
info = abi.encodePacked("\x19Ethereum Signed Message:\n32", hash);
return info;
}
/**
* @dev debug for hash
*/
function Debug_ethMessageHash(bytes32 hash) public pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package generated
import (
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
)
// BridgeRegistryABI is the input ABI used to generate the binding from.
const BridgeRegistryABI = "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_goAssetBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeBank\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_valset\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_goAssetBridge\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_bridgeBank\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_valset\",\"type\":\"address\"}],\"name\":\"LogContractsRegistered\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[],\"name\":\"bridgeBank\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"deployHeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"goAssetBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"valset\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
// BridgeRegistryFuncSigs maps the 4-byte function signature to its string representation.
var BridgeRegistryFuncSigs = map[string]string{
"0e41f373": "bridgeBank()",
"53d953b5": "deployHeight()",
"52712802": "goAssetBridge()",
"7dc0d1d0": "oracle()",
"7f54af0c": "valset()",
}
// BridgeRegistryBin is the compiled bytecode used for deploying new contracts.
var BridgeRegistryBin = "0x608060405234801561001057600080fd5b5060405161021b38038061021b8339818101604052608081101561003357600080fd5b508051602080830151604080850151606095860151600080546001600160a01b038089166001600160a01b031992831617928390556001805482891690841617908190556002805483881690851617908190556003805484881695169490941793849055436004558751948316855290821698840198909852968716828601529095169685019690965290519394919390927f039b733f31259b106f1d278c726870d5b28c7db22957d63df8dbaa70bd3a032a919081900360800190a150505050610118806101036000396000f3fe6080604052348015600f57600080fd5b506004361060505760003560e01c80630e41f3731460555780635271280214607757806353d953b514607d5780637dc0d1d01460955780637f54af0c14609b575b600080fd5b605b60a1565b604080516001600160a01b039092168252519081900360200190f35b605b60b0565b608360bf565b60408051918252519081900360200190f35b605b60c5565b605b60d4565b6001546001600160a01b031681565b6000546001600160a01b031681565b60045481565b6002546001600160a01b031681565b6003546001600160a01b03168156fea265627a7a72315820eff73eff513c47a2fcc472b30bdb6f42326d76edbf262fa57dba1d708aa0500164736f6c63430005100032"
// DeployBridgeRegistry deploys a new Ethereum contract, binding an instance of BridgeRegistry to it.
func DeployBridgeRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, _goAssetBridge common.Address, _bridgeBank common.Address, _oracle common.Address, _valset common.Address) (common.Address, *types.Transaction, *BridgeRegistry, error) {
parsed, err := abi.JSON(strings.NewReader(BridgeRegistryABI))
if err != nil {
return common.Address{}, nil, nil, err
}
address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(BridgeRegistryBin), backend, _goAssetBridge, _bridgeBank, _oracle, _valset)
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &BridgeRegistry{BridgeRegistryCaller: BridgeRegistryCaller{contract: contract}, BridgeRegistryTransactor: BridgeRegistryTransactor{contract: contract}, BridgeRegistryFilterer: BridgeRegistryFilterer{contract: contract}}, nil
}
// BridgeRegistry is an auto generated Go binding around an Ethereum contract.
type BridgeRegistry struct {
BridgeRegistryCaller // Read-only binding to the contract
BridgeRegistryTransactor // Write-only binding to the contract
BridgeRegistryFilterer // Log filterer for contract events
}
// BridgeRegistryCaller is an auto generated read-only Go binding around an Ethereum contract.
type BridgeRegistryCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BridgeRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract.
type BridgeRegistryTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BridgeRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type BridgeRegistryFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BridgeRegistrySession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type BridgeRegistrySession struct {
Contract *BridgeRegistry // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// BridgeRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type BridgeRegistryCallerSession struct {
Contract *BridgeRegistryCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// BridgeRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type BridgeRegistryTransactorSession struct {
Contract *BridgeRegistryTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// BridgeRegistryRaw is an auto generated low-level Go binding around an Ethereum contract.
type BridgeRegistryRaw struct {
Contract *BridgeRegistry // Generic contract binding to access the raw methods on
}
// BridgeRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type BridgeRegistryCallerRaw struct {
Contract *BridgeRegistryCaller // Generic read-only contract binding to access the raw methods on
}
// BridgeRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type BridgeRegistryTransactorRaw struct {
Contract *BridgeRegistryTransactor // Generic write-only contract binding to access the raw methods on
}
// NewBridgeRegistry creates a new instance of BridgeRegistry, bound to a specific deployed contract.
func NewBridgeRegistry(address common.Address, backend bind.ContractBackend) (*BridgeRegistry, error) {
contract, err := bindBridgeRegistry(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &BridgeRegistry{BridgeRegistryCaller: BridgeRegistryCaller{contract: contract}, BridgeRegistryTransactor: BridgeRegistryTransactor{contract: contract}, BridgeRegistryFilterer: BridgeRegistryFilterer{contract: contract}}, nil
}
// NewBridgeRegistryCaller creates a new read-only instance of BridgeRegistry, bound to a specific deployed contract.
func NewBridgeRegistryCaller(address common.Address, caller bind.ContractCaller) (*BridgeRegistryCaller, error) {
contract, err := bindBridgeRegistry(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &BridgeRegistryCaller{contract: contract}, nil
}
// NewBridgeRegistryTransactor creates a new write-only instance of BridgeRegistry, bound to a specific deployed contract.
func NewBridgeRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*BridgeRegistryTransactor, error) {
contract, err := bindBridgeRegistry(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &BridgeRegistryTransactor{contract: contract}, nil
}
// NewBridgeRegistryFilterer creates a new log filterer instance of BridgeRegistry, bound to a specific deployed contract.
func NewBridgeRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*BridgeRegistryFilterer, error) {
contract, err := bindBridgeRegistry(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &BridgeRegistryFilterer{contract: contract}, nil
}
// bindBridgeRegistry binds a generic wrapper to an already deployed contract.
func bindBridgeRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(BridgeRegistryABI))
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_BridgeRegistry *BridgeRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _BridgeRegistry.Contract.BridgeRegistryCaller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_BridgeRegistry *BridgeRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BridgeRegistry.Contract.BridgeRegistryTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_BridgeRegistry *BridgeRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _BridgeRegistry.Contract.BridgeRegistryTransactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_BridgeRegistry *BridgeRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _BridgeRegistry.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_BridgeRegistry *BridgeRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BridgeRegistry.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_BridgeRegistry *BridgeRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _BridgeRegistry.Contract.contract.Transact(opts, method, params...)
}
// BridgeBank is a free data retrieval call binding the contract method 0x0e41f373.
//
// Solidity: function bridgeBank() view returns(address)
func (_BridgeRegistry *BridgeRegistryCaller) BridgeBank(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _BridgeRegistry.contract.Call(opts, &out, "bridgeBank")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// BridgeBank is a free data retrieval call binding the contract method 0x0e41f373.
//
// Solidity: function bridgeBank() view returns(address)
func (_BridgeRegistry *BridgeRegistrySession) BridgeBank() (common.Address, error) {
return _BridgeRegistry.Contract.BridgeBank(&_BridgeRegistry.CallOpts)
}
// BridgeBank is a free data retrieval call binding the contract method 0x0e41f373.
//
// Solidity: function bridgeBank() view returns(address)
func (_BridgeRegistry *BridgeRegistryCallerSession) BridgeBank() (common.Address, error) {
return _BridgeRegistry.Contract.BridgeBank(&_BridgeRegistry.CallOpts)
}
// DeployHeight is a free data retrieval call binding the contract method 0x53d953b5.
//
// Solidity: function deployHeight() view returns(uint256)
func (_BridgeRegistry *BridgeRegistryCaller) DeployHeight(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _BridgeRegistry.contract.Call(opts, &out, "deployHeight")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// DeployHeight is a free data retrieval call binding the contract method 0x53d953b5.
//
// Solidity: function deployHeight() view returns(uint256)
func (_BridgeRegistry *BridgeRegistrySession) DeployHeight() (*big.Int, error) {
return _BridgeRegistry.Contract.DeployHeight(&_BridgeRegistry.CallOpts)
}
// DeployHeight is a free data retrieval call binding the contract method 0x53d953b5.
//
// Solidity: function deployHeight() view returns(uint256)
func (_BridgeRegistry *BridgeRegistryCallerSession) DeployHeight() (*big.Int, error) {
return _BridgeRegistry.Contract.DeployHeight(&_BridgeRegistry.CallOpts)
}
// GoAssetBridge is a free data retrieval call binding the contract method 0x52712802.
//
// Solidity: function goAssetBridge() view returns(address)
func (_BridgeRegistry *BridgeRegistryCaller) GoAssetBridge(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _BridgeRegistry.contract.Call(opts, &out, "goAssetBridge")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// GoAssetBridge is a free data retrieval call binding the contract method 0x52712802.
//
// Solidity: function goAssetBridge() view returns(address)
func (_BridgeRegistry *BridgeRegistrySession) GoAssetBridge() (common.Address, error) {
return _BridgeRegistry.Contract.GoAssetBridge(&_BridgeRegistry.CallOpts)
}
// GoAssetBridge is a free data retrieval call binding the contract method 0x52712802.
//
// Solidity: function goAssetBridge() view returns(address)
func (_BridgeRegistry *BridgeRegistryCallerSession) GoAssetBridge() (common.Address, error) {
return _BridgeRegistry.Contract.GoAssetBridge(&_BridgeRegistry.CallOpts)
}
// Oracle is a free data retrieval call binding the contract method 0x7dc0d1d0.
//
// Solidity: function oracle() view returns(address)
func (_BridgeRegistry *BridgeRegistryCaller) Oracle(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _BridgeRegistry.contract.Call(opts, &out, "oracle")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// Oracle is a free data retrieval call binding the contract method 0x7dc0d1d0.
//
// Solidity: function oracle() view returns(address)
func (_BridgeRegistry *BridgeRegistrySession) Oracle() (common.Address, error) {
return _BridgeRegistry.Contract.Oracle(&_BridgeRegistry.CallOpts)
}
// Oracle is a free data retrieval call binding the contract method 0x7dc0d1d0.
//
// Solidity: function oracle() view returns(address)
func (_BridgeRegistry *BridgeRegistryCallerSession) Oracle() (common.Address, error) {
return _BridgeRegistry.Contract.Oracle(&_BridgeRegistry.CallOpts)
}
// Valset is a free data retrieval call binding the contract method 0x7f54af0c.
//
// Solidity: function valset() view returns(address)
func (_BridgeRegistry *BridgeRegistryCaller) Valset(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _BridgeRegistry.contract.Call(opts, &out, "valset")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// Valset is a free data retrieval call binding the contract method 0x7f54af0c.
//
// Solidity: function valset() view returns(address)
func (_BridgeRegistry *BridgeRegistrySession) Valset() (common.Address, error) {
return _BridgeRegistry.Contract.Valset(&_BridgeRegistry.CallOpts)
}
// Valset is a free data retrieval call binding the contract method 0x7f54af0c.
//
// Solidity: function valset() view returns(address)
func (_BridgeRegistry *BridgeRegistryCallerSession) Valset() (common.Address, error) {
return _BridgeRegistry.Contract.Valset(&_BridgeRegistry.CallOpts)
}
// BridgeRegistryLogContractsRegisteredIterator is returned from FilterLogContractsRegistered and is used to iterate over the raw logs and unpacked data for LogContractsRegistered events raised by the BridgeRegistry contract.
type BridgeRegistryLogContractsRegisteredIterator struct {
Event *BridgeRegistryLogContractsRegistered // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *BridgeRegistryLogContractsRegisteredIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(BridgeRegistryLogContractsRegistered)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(BridgeRegistryLogContractsRegistered)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *BridgeRegistryLogContractsRegisteredIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *BridgeRegistryLogContractsRegisteredIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// BridgeRegistryLogContractsRegistered represents a LogContractsRegistered event raised by the BridgeRegistry contract.
type BridgeRegistryLogContractsRegistered struct {
GoAssetBridge common.Address
BridgeBank common.Address
Oracle common.Address
Valset common.Address
Raw types.Log // Blockchain specific contextual infos
}
// FilterLogContractsRegistered is a free log retrieval operation binding the contract event 0x039b733f31259b106f1d278c726870d5b28c7db22957d63df8dbaa70bd3a032a.
//
// Solidity: event LogContractsRegistered(address _goAssetBridge, address _bridgeBank, address _oracle, address _valset)
func (_BridgeRegistry *BridgeRegistryFilterer) FilterLogContractsRegistered(opts *bind.FilterOpts) (*BridgeRegistryLogContractsRegisteredIterator, error) {
logs, sub, err := _BridgeRegistry.contract.FilterLogs(opts, "LogContractsRegistered")
if err != nil {
return nil, err
}
return &BridgeRegistryLogContractsRegisteredIterator{contract: _BridgeRegistry.contract, event: "LogContractsRegistered", logs: logs, sub: sub}, nil
}
// WatchLogContractsRegistered is a free log subscription operation binding the contract event 0x039b733f31259b106f1d278c726870d5b28c7db22957d63df8dbaa70bd3a032a.
//
// Solidity: event LogContractsRegistered(address _goAssetBridge, address _bridgeBank, address _oracle, address _valset)
func (_BridgeRegistry *BridgeRegistryFilterer) WatchLogContractsRegistered(opts *bind.WatchOpts, sink chan<- *BridgeRegistryLogContractsRegistered) (event.Subscription, error) {
logs, sub, err := _BridgeRegistry.contract.WatchLogs(opts, "LogContractsRegistered")
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(BridgeRegistryLogContractsRegistered)
if err := _BridgeRegistry.contract.UnpackLog(event, "LogContractsRegistered", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseLogContractsRegistered is a log parse operation binding the contract event 0x039b733f31259b106f1d278c726870d5b28c7db22957d63df8dbaa70bd3a032a.
//
// Solidity: event LogContractsRegistered(address _goAssetBridge, address _bridgeBank, address _oracle, address _valset)
func (_BridgeRegistry *BridgeRegistryFilterer) ParseLogContractsRegistered(log types.Log) (*BridgeRegistryLogContractsRegistered, error) {
event := new(BridgeRegistryLogContractsRegistered)
if err := _BridgeRegistry.contract.UnpackLog(event, "LogContractsRegistered", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
......@@ -8,6 +8,7 @@ strapp=${strcmd%/cmd*}
SRC_EBCLI=github.com/33cn/plugin/plugin/dapp/cross2eth/ebcli
SRC_EBRELAYER=github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer
SRC_BOSS4XCLI=github.com/33cn/plugin/plugin/dapp/cross2eth/boss4x
OUT_DIR="${1}/$strapp"
FLAG=$2
......
......@@ -54,7 +54,7 @@ function evm_callQuery() {
local parameter=$1
local callerAddr=$2
local resok=$3
local methodName=$4
local name=$4
req='{"method":"Chain33.Query","params":[{"execer":"evm","funcName":"GetPackData","payload":{"abi":"'${erc20_abi}'","parameter":"'${parameter}'"}}]}'
chain33_Http "$req" "${MAIN_HTTP}" '(.result != null)' "GetPackData" ".result.packData"
......@@ -64,7 +64,7 @@ function evm_callQuery() {
chain33_Http "$req" "${MAIN_HTTP}" '(.result != null)' "Query" ".result.rawData"
echo "$RETURN_RESP"
req='{"method":"Chain33.Query","params":[{"execer":"evm","funcName":"GetUnpackData","payload":{"abi":"'${erc20_abi}'","methodName":"'${methodName}'","data":"'${RETURN_RESP}'"}}]}'
req='{"method":"Chain33.Query","params":[{"execer":"evm","funcName":"GetUnpackData","payload":{"abi":"'${erc20_abi}'","name":"'${name}'","data":"'${RETURN_RESP}'"}}]}'
chain33_Http "$req" "${MAIN_HTTP}" '(.result != null)' "GetUnpackData" ".result.unpackData[0]"
echo "$RETURN_RESP"
......
......@@ -153,6 +153,63 @@ func Unpack(data []byte, methodName, abiData string) (output []*Param, err error
return
}
//同时支持input,output和event三种数据的unpack
func UnpackAllTypes(data []byte, name, abiData string) (output []*Param, err error) {
if len(data) == 0 {
log.Info("Unpack", "Data len", 0, "name", name)
return output, err
}
// 解析ABI数据结构,获取本次调用的方法对象
abi, err := JSON(strings.NewReader(abiData))
if err != nil {
return output, err
}
var values []interface{}
var arguments Arguments
if method, ok := abi.Methods[name]; ok {
if len(data)%32 == 0 {
values, err = method.Outputs.UnpackValues(data)
arguments = method.Outputs
} else if len(data[4:])%32 == 0 {
values, err = method.Inputs.UnpackValues(data[4:])
arguments = method.Inputs
} else {
return output, errors.New("UnpackAllTypes: improperly formatted data")
}
if arguments.LengthNonIndexed() == 0 {
return output, nil
}
} else if event, ok := abi.Events[name]; ok {
values, err = event.Inputs.UnpackValues(data)
arguments = event.Inputs
} else {
return output, errors.New("UnpackAllTypes: could not locate named method or event")
}
if err != nil {
return output, err
}
if len(arguments) == 0 || len(values) != len(arguments) {
return output, errors.New("wrong data to unpack")
}
output = []*Param{}
for i, v := range values {
arg := arguments[i]
pval := &Param{Name: arg.Name, Type: arg.Type.String(), Value: v}
if arg.Type.String() == "address" {
pval.Value = v.(common.Hash160Address).ToAddress().String()
log.Info("Unpack address", "address", pval.Value)
}
output = append(output, pval)
}
return
}
// Param 返回值参数结构定义
type Param struct {
// Name 参数名称
......
......@@ -204,7 +204,7 @@ func (evm *EVMExecutor) Query_GetUnpackData(in *evmtypes.EvmGetUnpackDataReq) (t
return nil, errors.New("common.FromHex failed due to:" + err.Error())
}
outputs, err := evmAbi.Unpack(data, in.MethodName, in.Abi)
outputs, err := evmAbi.UnpackAllTypes(data, in.Name, in.Abi)
if err != nil {
return nil, errors.New("unpack evm return error" + err.Error())
}
......
package executor
import (
"fmt"
"math/big"
"testing"
"github.com/33cn/chain33/common"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
"gotest.tools/assert"
)
const abiStr = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"URI\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"balanceOfBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"burnTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTokenInfo\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"getUserTokenIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"mintTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"tokenInfo\",\"type\":\"string\"}],\"name\":\"setTokenInfo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"uri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"
//mintTokenBatch(address owner, uint256[] calldata tokenIds, uint256[] calldata amounts)
func Test_Pack(t *testing.T) {
_, packData, err := evmAbi.Pack("mintTokenBatch(14KEKbYtKKQm4wMthSK9J4La4nAiidGozt, [1,2,3], [100, 200, 300])", abiStr, false)
assert.Equal(t, nil, err)
packStr := common.ToHex(packData)
fmt.Println("packStr = ", packStr)
//0xa08fad67000000000000000000000000245afbf176934ccdd7ca291a8dddaa13c8184822000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c
}
func Test_Unpack(t *testing.T) {
_, packData, err := evmAbi.Pack("mintTokenBatch(14KEKbYtKKQm4wMthSK9J4La4nAiidGozt, [1,2,3], [100, 200, 300])", abiStr, false)
assert.Equal(t, nil, err)
packStr := common.ToHex(packData)
fmt.Println("packStr = ", packStr)
outputs, err := evmAbi.Unpack(packData, "mintTokenBatch", abiStr)
assert.Equal(t, nil, err)
for i, info := range outputs {
fmt.Println(i, "th info = ", info)
}
}
func Test_UnpackEvent(t *testing.T) {
//event TransferToken(address owner, address to, uint256 tokenId, uint256 amount);
packData, err := common.FromHex("0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000098968100000000000000000000000000000000000000000000000000000000009896820000000000000000000000000000000000000000000000000000000000989683000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000c8")
assert.Equal(t, nil, err)
outputs, err := evmAbi.UnpackAllTypes(packData, "TransferToken", abiStr)
assert.Equal(t, nil, err)
for i, info := range outputs {
fmt.Println(i, "th info = ", info)
}
}
const BridgeBankABI = "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_operatorAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oracleAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_ethereumBridgeAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_beneficiary\",\"type\":\"address\"}],\"name\":\"LogBridgeTokenMint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_ownerFrom\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_ethereumReceiver\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"LogEthereumTokenBurn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_to\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"LogLock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"LogNewBridgeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"LogUnlock\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"addToken2LockList\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"bridgeTokenCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"bridgeTokenCreated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridgeTokenWhitelist\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_ethereumReceiver\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_ethereumTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"burnBridgeTokens\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_percents\",\"type\":\"uint8\"}],\"name\":\"configLockedTokenOfflineSave\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_offlineSave\",\"type\":\"address\"}],\"name\":\"configOfflineSaveAccount\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createNewBridgeToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ethereumBridge\",\"outputs\":[{\"internalType\":\"contractEthereumBridge\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_id\",\"type\":\"bytes32\"}],\"name\":\"getEthereumDepositStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"getLockedTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"getToken2address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"getofflineSaveCfg\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"hasBridgeTokenCreated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"highThreshold\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_recipient\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"lock\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lockNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lockedFunds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lowThreshold\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_ethereumSender\",\"type\":\"bytes\"},{\"internalType\":\"addresspayable\",\"name\":\"_intendedRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mintBridgeTokens\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"offlineSave\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"offlineSaveCfgs\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_percents\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"operator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contractOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"token2address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"tokenAllow2Lock\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unlock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_id\",\"type\":\"bytes32\"}],\"name\":\"viewEthereumDeposit\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
func Test_UnpackEventLock(t *testing.T) {
//event TransferToken(address owner, address to, uint256 tokenId, uint256 amount);
packData, err := common.FromHex("0x000000000000000000000000809b923eea05ad681a0ec1459e613cd7af7f5f1800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000014bc333839e37bc7faad0137abae2275030555101f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000034254590000000000000000000000000000000000000000000000000000000000")
assert.Equal(t, nil, err)
outputs, err := evmAbi.UnpackAllTypes(packData, "LogLock", BridgeBankABI)
assert.Equal(t, nil, err)
for i, info := range outputs {
fmt.Println(i, "th info = ", info)
}
}
//UnpackLogLock module=cross2eth_relayer
//value=500000000
//symbol=BTY
//token addr on chain33 evm=1111111111111111111114oLvT2
//chain33 sender=1Cj1rqUenPmkeD6A8MGEzkBKQFN2H9yL3x
//ethereum recipient=0xbc333839E37bc7fAAD0137aBaE2275030555101f
//nonce=1
const BridgeBankABIBridgevmxgo = "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_operatorAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oracleAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_goAssetBridgeAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_beneficiary\",\"type\":\"address\"}],\"name\":\"LogBridgeTokenMint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_ownerFrom\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_goAssetReceiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"LogGoAssetTokenBurn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"LogLock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"LogNewBridgeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"LogUnlock\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"addToken2LockList\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"bridgeTokenCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"bridgeTokenCreated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridgeTokenWhitelist\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_goAssetReceiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_goAssetTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"burnBridgeTokens\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_percents\",\"type\":\"uint8\"}],\"name\":\"configLockedTokenOfflineSave\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_offlineSave\",\"type\":\"address\"}],\"name\":\"configOfflineSaveAccount\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createNewBridgeToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_id\",\"type\":\"bytes32\"}],\"name\":\"getGoAssetDepositStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"getLockedTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"getToken2address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"getofflineSaveCfg\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"goAssetBridge\",\"outputs\":[{\"internalType\":\"contractGoAssetBridge\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"hasBridgeTokenCreated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"highThreshold\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"lock\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lockNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lockedFunds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lowThreshold\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_goAssetSender\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"_intendedRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mintBridgeTokens\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"offlineSave\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"offlineSaveCfgs\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_percents\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"operator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contractOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"token2address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"tokenAllow2Lock\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unlock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_id\",\"type\":\"bytes32\"}],\"name\":\"viewGoAssetDeposit\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
//'lock(1BCGLhdcdthNutQowV2YShuuN9fJRRGLxu, 195ycckxqnxyaQeLYTQvgETr1vsEp4NYmP, 500000000)'
func Test_UnpackEventLockOfBridgevmxgo(t *testing.T) {
//event TransferToken(address owner, address to, uint256 tokenId, uint256 amount);
packData, err := common.FromHex("0x000000000000000000000000143b825fde7a42043b2cedef6b4c6f57c04d71b70000000000000000000000006fd2a3693c289b6c3c211f5d2f85ce145d1afaeb00000000000000000000000058b1edde0fc37c0f7f4a23d1c2df488ec5df0fe100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000001dcd6500000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000034554480000000000000000000000000000000000000000000000000000000000")
assert.Equal(t, nil, err)
outputs, err := evmAbi.UnpackAllTypes(packData, "LogLock", BridgeBankABIBridgevmxgo)
assert.Equal(t, nil, err)
for i, info := range outputs {
fmt.Println(i, "th info = ", info)
}
}
//'lock(1BCGLhdcdthNutQowV2YShuuN9fJRRGLxu, 195ycckxqnxyaQeLYTQvgETr1vsEp4NYmP, 500000000)'
//"7750c9f0": "lock(address,address,uint256)",
func Test_UnpackInputLockOfBridgevmxgo(t *testing.T) {
methodName, packDataOrigin, err := evmAbi.Pack("lock(1BCGLhdcdthNutQowV2YShuuN9fJRRGLxu, 195ycckxqnxyaQeLYTQvgETr1vsEp4NYmP, 500000000)", BridgeBankABIBridgevmxgo, false)
assert.Equal(t, nil, err)
fmt.Println("methodName", methodName)
fmt.Println("packDataOrigin", common.ToHex(packDataOrigin))
//event TransferToken(address owner, address to, uint256 tokenId, uint256 amount);
packData, err := common.FromHex("0x7750c9f00000000000000000000000006fd2a3693c289b6c3c211f5d2f85ce145d1afaeb00000000000000000000000058b1edde0fc37c0f7f4a23d1c2df488ec5df0fe1000000000000000000000000000000000000000000000000000000001dcd6500")
//7750c9f0
//0000000000000000000000006fd2a3693c289b6c3c211f5d2f85ce145d1afaeb
//00000000000000000000000058b1edde0fc37c0f7f4a23d1c2df488ec5df0fe1
//000000000000000000000000000000000000000000000000000000001dcd6500
assert.Equal(t, nil, err)
outputs, err := evmAbi.UnpackAllTypes(packData, "lock", BridgeBankABIBridgevmxgo)
assert.Equal(t, nil, err)
for i, info := range outputs {
fmt.Println(i, "th info = ", info)
}
correct := 0
for _, para := range outputs {
switch para.Name {
case "_recipient":
assert.Equal(t, para.Value, "1BCGLhdcdthNutQowV2YShuuN9fJRRGLxu")
correct++
case "_amount":
assert.Equal(t, para.Value.(*big.Int).Int64(), int64(500000000))
correct++
case "_token":
assert.Equal(t, para.Value, "195ycckxqnxyaQeLYTQvgETr1vsEp4NYmP")
correct++
}
}
assert.Equal(t, correct, 3)
}
......@@ -202,7 +202,7 @@ message EvmGetPackDataRespose {
message EvmGetUnpackDataReq {
string abi = 1;
string methodName = 2;
string name = 2;
string data = 3;
}
......
......@@ -1863,7 +1863,7 @@ type EvmGetUnpackDataReq struct {
unknownFields protoimpl.UnknownFields
Abi string `protobuf:"bytes,1,opt,name=abi,proto3" json:"abi,omitempty"`
MethodName string `protobuf:"bytes,2,opt,name=methodName,proto3" json:"methodName,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
}
......@@ -1906,9 +1906,9 @@ func (x *EvmGetUnpackDataReq) GetAbi() string {
return ""
}
func (x *EvmGetUnpackDataReq) GetMethodName() string {
func (x *EvmGetUnpackDataReq) GetName() string {
if x != nil {
return x.MethodName
return x.Name
}
return ""
}
......@@ -2169,18 +2169,17 @@ var file_evmcontract_proto_rawDesc = []byte{
0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x22, 0x33, 0x0a, 0x15, 0x45, 0x76, 0x6d, 0x47, 0x65, 0x74,
0x50, 0x61, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x12,
0x1a, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x22, 0x5b, 0x0a, 0x13, 0x45,
0x09, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x22, 0x4f, 0x0a, 0x13, 0x45,
0x76, 0x6d, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52,
0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x62, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x61, 0x62, 0x69, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4e, 0x61,
0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x39, 0x0a, 0x17, 0x45, 0x76, 0x6d, 0x47,
0x65, 0x74, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x44, 0x61, 0x74,
0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x44,
0x61, 0x74, 0x61, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2e, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x03, 0x61, 0x62, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x39, 0x0a, 0x17,
0x45, 0x76, 0x6d, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x75, 0x6e, 0x70, 0x61, 0x63,
0x6b, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x75, 0x6e, 0x70,
0x61, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2e, 0x2f, 0x74, 0x79,
0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
......
all:
bash build.sh $(OUT) $(FLAG)
#!/bin/bash
# 官方ci集成脚本
strpwd=$(pwd)
strcmd=${strpwd##*dapp/}
strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
#FLAG=$2
mkdir -p "${OUT_DIR}"
cp ./build/* "${OUT_DIR}"
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
source ../dapp-test-common.sh
MAIN_HTTP=""
tokenExecName="token"
ExecName="evmxgo"
privateKey="0x4dcb00c7d01a3d377c0d5a14cd7ec91798a74c8b41896c5d21fc8b9bf4b40e42"
function updateConfig() {
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.CreateTransaction","params":[{"execer":"manage","actionName":"Modify","payload":{"key":"evmxgo-mint-DOG","value":"{\"address\":\"address1234\",\"precision\":4,\"introduction\":\"介绍\"}","op":"add","addr":""}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "update config create tx" 1
return
fi
signRawTxAndQuery "$FUNCNAME" "$privateKey" "${unsignedTx}"
}
function evmxgo_mint() {
local data='{"jsonrpc":"2.0","id":1,"method":"Chain33.CreateTransaction","params":[{"execer":"evmxgo","actionName":"Mint","payload":{"symbol":"DOG","amount":10000000}}]}'
unsignedTx=$(curl -s --data-binary "$data" -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "evmxgo mint create tx" 1
return
fi
signRawTxAndQuery "$FUNCNAME" "$privateKey" "${unsignedTx}"
}
function evmxgo_burn() {
local data='{"jsonrpc":"2.0","id":2,"method":"Chain33.CreateTransaction","params":[{"execer":"evmxgo","actionName":"Burn","payload":{"symbol":"DOG","amount":10000000}}]}'
unsignedTx=$(curl -s --data-binary "$data" -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "evmxgo mint create tx" 1
return
fi
signRawTxAndQuery "$FUNCNAME" "$privateKey" "${unsignedTx}"
}
function evmxgo_transfer() {
addr=$1
symbol=$2
local data='{"jsonrpc":"2.0","id":2,"method":"Chain33.CreateTransaction","params":[{"execer": "'"${ExecName}"'","actionName":"Transfer","payload": {"cointoken":"'"${symbol}"'", "amount": "10000000", "note": "", "to": "'"${addr}"'"}}]}'
unsignedTx=$(curl -s --data-binary "${data}" -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "token transfer create tx" 1
return
fi
signRawTxAndQuery "$FUNCNAME" "$privateKey" "${unsignedTx}"
}
function evmxgo_transfer_exec() {
addr=$1
symbol=$2
local data='{"jsonrpc":"2.0","id":1,"method":"Chain33.CreateTransaction","params":[{"execer":"'"${ExecName}"'","actionName":"TransferToExec","payload":{"cointoken":"'"${symbol}"'","amount":10000,"note":"","execName":"token","to":"12hpJBHybh1mSyCijQ2MQJPk7z7kZ7jnQa"}}]}'
unsignedTx=$(curl -s --data-binary "${data}" -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "token transfer create tx" 1
return
fi
signRawTxAndQuery "$FUNCNAME" "$privateKey" "${unsignedTx}"
}
function evmxgo_withdraw() {
addr=$1
symbol=$2
local data='{"jsonrpc":"2.0","id":1,"method":"Chain33.CreateTransaction","params":[{"execer":"'"${ExecName}"'","actionName":"Withdraw","payload":{"cointoken":"'"${symbol}"'","amount":1000,"note":"","execName":"'"${tokenExecName}"'","to":"'"${addr}"'"}}]}'
unsignedTx=$(curl -s --data-binary "${data}" -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "token transfer create tx" 1
return
fi
signRawTxAndQuery "$FUNCNAME" "$privateKey" "${unsignedTx}"
}
# 查询交易的执行结果
# 根据传入的规则,校验查询的结果 (参数1: 校验规则 参数2: 预期匹配结果)
function queryTransaction() {
validator=$1
expectRes=$2
echo "txhash=${RAW_TX_HASH}"
res=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.QueryTransaction","params":[{"hash":"'"${RAW_TX_HASH}"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r "${validator}")
if [ "${res}" != "${expectRes}" ]; then
return 1
else
return 0
fi
}
function signRawTxAndQuery() {
chain33_SignAndSendTx "$3" "$2" "${MAIN_HTTP}"
queryTransaction ".error | not" "true"
echo_rst "$1 queryExecRes" "$?"
}
function init() {
updateConfig
}
function run_test() {
local ip=$1
evmxgo_mint
evmxgo_burn
evmxgo_transfer "17EVv6tW2HzE73TVB6YXQYThQJxa7kuZb8" "DOG"
evmxgo_transfer_exec "12hpJBHybh1mSyCijQ2MQJPk7z7kZ7jnQa" "DOG"
evmxgo_withdraw "12hpJBHybh1mSyCijQ2MQJPk7z7kZ7jnQa" "DOG"
}
function main() {
chain33_RpcTestBegin evmxgo
local ip=$1
MAIN_HTTP=$ip
echo "main_ip=$MAIN_HTTP"
init
run_test "$MAIN_HTTP"
chain33_RpcTestRst evmxgo "$CASE_ERR"
}
chain33_debug_function main "http://ip:port/"
/*Package commands implement dapp client commands*/
package commands
import (
"encoding/json"
"fmt"
"os"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/system/dapp/commands"
cmdtypes "github.com/33cn/chain33/system/dapp/commands/types"
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
/*
* 实现合约对应客户端
*/
var (
tokenSymbol string
)
// Cmd evmxgo client command
func Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "evmxgo",
Short: "evmxgo command",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
//add sub command
CreateTokenTransferCmd(),
CreateTokenWithdrawCmd(),
GetTokensCreatedCmd(),
GetTokenAssetsCmd(),
CreateTokenTransferExecCmd(),
CreateRawTokenMintTxCmd(),
CreateRawTokenBurnTxCmd(),
GetTokenLogsCmd(),
GetTokenCmd(),
QueryTxCmd(),
)
return cmd
}
// CreateTokenTransferCmd create raw transfer tx
func CreateTokenTransferCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "transfer",
Short: "Create a evmxgo transfer transaction",
Run: createTokenTransfer,
}
addCreateTokenTransferFlags(cmd)
return cmd
}
func addCreateTokenTransferFlags(cmd *cobra.Command) {
cmd.Flags().StringP("to", "t", "", "receiver account address")
cmd.MarkFlagRequired("to")
cmd.Flags().Float64P("amount", "a", 0, "transaction amount")
cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("symbol", "s", "", "token symbol")
cmd.MarkFlagRequired("symbol")
}
func createTokenTransfer(cmd *cobra.Command, args []string) {
commands.CreateAssetTransfer(cmd, args, evmxgotypes.EvmxgoX)
}
// CreateTokenTransferExecCmd create raw transfer tx
func CreateTokenTransferExecCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "send_exec",
Short: "Create a evmxgo send to executor transaction",
Run: createTokenSendToExec,
}
addCreateTokenSendToExecFlags(cmd)
return cmd
}
func addCreateTokenSendToExecFlags(cmd *cobra.Command) {
cmd.Flags().StringP("exec", "e", "", "receiver executor address")
cmd.MarkFlagRequired("exec")
cmd.Flags().Float64P("amount", "a", 0, "transaction amount")
cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("symbol", "s", "", "token symbol")
cmd.MarkFlagRequired("symbol")
}
func createTokenSendToExec(cmd *cobra.Command, args []string) {
commands.CreateAssetSendToExec(cmd, args, evmxgotypes.EvmxgoX)
}
// CreateTokenWithdrawCmd create raw withdraw tx
func CreateTokenWithdrawCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "withdraw",
Short: "Create a evmxgo withdraw transaction",
Run: createTokenWithdraw,
}
addCreateTokenWithdrawFlags(cmd)
return cmd
}
func addCreateTokenWithdrawFlags(cmd *cobra.Command) {
cmd.Flags().StringP("exec", "e", "", "execer withdrawn from")
cmd.MarkFlagRequired("exec")
cmd.Flags().Float64P("amount", "a", 0, "withdraw amount")
cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("symbol", "s", "", "token symbol")
cmd.MarkFlagRequired("symbol")
}
func createTokenWithdraw(cmd *cobra.Command, args []string) {
commands.CreateAssetWithdraw(cmd, args, evmxgotypes.EvmxgoX)
}
// GetTokensCreatedCmd get finish created tokens
func GetTokensCreatedCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "created",
Short: "Get finish created tokens",
Run: getFinishCreatedTokens,
}
return cmd
}
func getFinishCreatedTokens(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
cfg, err := cmdtypes.GetChainConfig(rpcLaddr)
if err != nil {
fmt.Fprintln(os.Stderr, errors.Wrapf(err, "GetChainConfig"))
return
}
var reqtokens evmxgotypes.ReqEvmxgos
reqtokens.QueryAll = true
var params rpctypes.Query4Jrpc
params.Execer = getRealExecName(paraName, "evmxgo")
params.FuncName = "GetTokens"
params.Payload = types.MustPBToJSON(&reqtokens)
rpc, err := jsonclient.NewJSONClient(rpcLaddr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var res evmxgotypes.ReplyEvmxgos
err = rpc.Call("Chain33.Query", params, &res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
for _, createdToken := range res.Tokens {
createdToken.Total = createdToken.Total / cfg.TokenPrecision
//fmt.Printf("---The %dth Finish Created token is below--------------------\n", i)
data, err := json.MarshalIndent(createdToken, "", " ")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(string(data))
}
}
// GetTokenAssetsCmd get token assets
func GetTokenAssetsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "assets",
Short: "Get evmxgo assets",
Run: tokenAssets,
}
addTokenAssetsFlags(cmd)
return cmd
}
func addTokenAssetsFlags(cmd *cobra.Command) {
cmd.Flags().StringP("exec", "e", "", "execer name")
cmd.MarkFlagRequired("exec")
cmd.Flags().StringP("addr", "a", "", "account address")
cmd.MarkFlagRequired("addr")
}
func tokenAssets(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
addr, _ := cmd.Flags().GetString("addr")
execer, _ := cmd.Flags().GetString("exec")
cfg, err := cmdtypes.GetChainConfig(rpcLaddr)
if err != nil {
fmt.Fprintln(os.Stderr, errors.Wrapf(err, "GetChainConfig"))
return
}
execer = getRealExecName(paraName, execer)
req := evmxgotypes.ReqAccountEvmxgoAssets{
Address: addr,
Execer: execer,
}
var params rpctypes.Query4Jrpc
params.Execer = getRealExecName(paraName, "evmxgo")
params.FuncName = "GetAccountTokenAssets"
params.Payload = types.MustPBToJSON(&req)
var res evmxgotypes.ReplyAccountEvmxgoAssets
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.SetResultCbExt(parseTokenAssetsRes)
ctx.RunExt(cfg)
}
func parseTokenAssetsRes(arg ...interface{}) (interface{}, error) {
res := arg[0].(*evmxgotypes.ReplyAccountEvmxgoAssets)
cfg := arg[1].(*rpctypes.ChainConfigInfo)
var result []*evmxgotypes.EvmxgoAccountResult
for _, ta := range res.EvmxgoAssets {
balanceResult := types.FormatAmount2FloatDisplay(ta.Account.Balance, cfg.TokenPrecision, true)
frozenResult := types.FormatAmount2FloatDisplay(ta.Account.Frozen, cfg.TokenPrecision, true)
tokenAccount := &evmxgotypes.EvmxgoAccountResult{
Token: ta.Symbol,
Addr: ta.Account.Addr,
Currency: ta.Account.Currency,
Balance: balanceResult,
Frozen: frozenResult,
}
result = append(result, tokenAccount)
}
return result, nil
}
// CreateRawTokenMintTxCmd create raw token mintage transaction
func CreateRawTokenMintTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "mint",
Short: "Create a mint evmxgo transaction",
Run: tokenMint,
}
addTokenMintFlags(cmd)
return cmd
}
func addTokenMintFlags(cmd *cobra.Command) {
cmd.Flags().StringP("symbol", "s", "", "token symbol")
cmd.MarkFlagRequired("symbol")
cmd.Flags().Float64P("amount", "a", 0, "amount of mintage")
cmd.MarkFlagRequired("amount")
cmd.Flags().Float64P("fee", "f", 0, "token transaction fee")
}
func tokenMint(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
symbol, _ := cmd.Flags().GetString("symbol")
amount, _ := cmd.Flags().GetFloat64("amount")
cfg, err := cmdtypes.GetChainConfig(rpcLaddr)
if err != nil {
fmt.Fprintln(os.Stderr, errors.Wrapf(err, "GetChainConfig"))
return
}
amountInt64, err := types.FormatFloatDisplay2Value(amount, cfg.CoinPrecision)
if err != nil {
fmt.Fprintln(os.Stderr, errors.Wrapf(err, "FormatFloatDisplay2Value.amount"))
return
}
params := &evmxgotypes.EvmxgoMint{
Symbol: symbol,
Amount: amountInt64,
}
ctx := jsonclient.NewRPCCtx(rpcLaddr, "evmxgo.CreateRawTokenMintTx", params, nil)
ctx.RunWithoutMarshal()
}
// CreateRawTokenBurnTxCmd create raw token burn transaction
func CreateRawTokenBurnTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "burn",
Short: "Create a burn token transaction",
Run: tokenBurn,
}
addTokenBurnFlags(cmd)
return cmd
}
func addTokenBurnFlags(cmd *cobra.Command) {
cmd.Flags().StringP("symbol", "s", "", "token symbol")
cmd.MarkFlagRequired("symbol")
cmd.Flags().Float64P("amount", "a", 0, "amount of burn")
cmd.MarkFlagRequired("amount")
cmd.Flags().Float64P("fee", "f", 0, "token transaction fee")
}
func tokenBurn(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
symbol, _ := cmd.Flags().GetString("symbol")
amount, _ := cmd.Flags().GetFloat64("amount")
cfg, err := cmdtypes.GetChainConfig(rpcLaddr)
if err != nil {
fmt.Fprintln(os.Stderr, errors.Wrapf(err, "GetChainConfig"))
return
}
amountInt64, err := types.FormatFloatDisplay2Value(amount, cfg.CoinPrecision)
if err != nil {
fmt.Fprintln(os.Stderr, errors.Wrapf(err, "FormatFloatDisplay2Value.amount"))
return
}
params := &evmxgotypes.EvmxgoBurn{
Symbol: symbol,
Amount: amountInt64,
}
ctx := jsonclient.NewRPCCtx(rpcLaddr, "token.CreateRawTokenBurnTx", params, nil)
ctx.RunWithoutMarshal()
}
// GetTokenLogsCmd get logs of token
func GetTokenLogsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "logs",
Short: "Get logs of token",
Run: getTokenLogs,
}
getTokenLogsFlags(cmd)
return cmd
}
func getTokenLogs(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
symbol, _ := cmd.Flags().GetString("symbol")
var params rpctypes.Query4Jrpc
params.Execer = getRealExecName(paraName, "evmxgo")
params.FuncName = "GetTokenHistory"
params.Payload = types.MustPBToJSON(&types.ReqString{Data: symbol})
rpc, err := jsonclient.NewJSONClient(rpcLaddr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var res evmxgotypes.ReplyEvmxgoLogs
err = rpc.Call("Chain33.Query", params, &res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
data, err := json.MarshalIndent(res, "", " ")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(string(data))
}
func getTokenLogsFlags(cmd *cobra.Command) {
cmd.Flags().StringP("symbol", "s", "", "token symbol")
cmd.MarkFlagRequired("symbol")
}
// GetTokenCmd get token
func GetTokenCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "info",
Short: "Get token info",
Run: getToken,
}
addGetTokenFlags(cmd)
return cmd
}
func addGetTokenFlags(cmd *cobra.Command) {
cmd.Flags().StringP("symbol", "s", "", "token symbol")
cmd.MarkFlagRequired("symbol")
}
func getToken(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
symbol, _ := cmd.Flags().GetString("symbol")
var reqtoken types.ReqString
reqtoken.Data = symbol
var params rpctypes.Query4Jrpc
params.Execer = getRealExecName(paraName, "token")
params.FuncName = "GetTokenInfo"
params.Payload = types.MustPBToJSON(&reqtoken)
rpc, err := jsonclient.NewJSONClient(rpcLaddr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var res evmxgotypes.LocalEvmxgo
err = rpc.Call("Chain33.Query", params, &res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
data, err := json.MarshalIndent(res, "", " ")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(string(data))
}
// QueryTxCmd get tx by address
func QueryTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "query_tx",
Short: "Query transaction by token symbol",
Run: queryTx,
}
addQueryTxFlags(cmd)
return cmd
}
func addQueryTxFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "account address")
cmd.Flags().StringP("symbol", "s", "", "token symbol")
cmd.MarkFlagRequired("symbol")
cmd.Flags().Int32P("flag", "f", 0, "transaction type(0: all txs relevant to addr, 1: addr as sender, 2: addr as receiver) (default 0)")
cmd.Flags().Int32P("count", "c", 10, "maximum return number of transactions")
cmd.Flags().Int32P("direction", "d", 0, "query direction from height:index(0: positive order -1:negative order) (default 0)")
cmd.Flags().Int64P("height", "t", -1, "transaction's block height(-1: from latest txs, >=0: query from height)")
cmd.Flags().Int64P("index", "i", 0, "query from index of tx in block height[0-100000] (default 0)")
}
func queryTx(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
addr, _ := cmd.Flags().GetString("addr")
flag, _ := cmd.Flags().GetInt32("flag")
count, _ := cmd.Flags().GetInt32("count")
direction, _ := cmd.Flags().GetInt32("direction")
height, _ := cmd.Flags().GetInt64("height")
index, _ := cmd.Flags().GetInt64("index")
symbol, _ := cmd.Flags().GetString("symbol")
req := evmxgotypes.ReqEvmxgoTx{
Symbol: symbol,
Addr: addr,
Flag: flag,
Count: count,
Direction: direction,
Height: height,
Index: index,
}
var params rpctypes.Query4Jrpc
params.Execer = getRealExecName(paraName, "evmxgo")
params.FuncName = "GetTxByToken"
params.Payload = types.MustPBToJSON(&req)
var res types.ReplyTxInfos
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package commands
import (
"strings"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
)
// GetExecAddr 获取执行器地址
func GetExecAddr(exec string) (string, error) {
if ok := types.IsAllowExecName([]byte(exec), []byte(exec)); !ok {
return "", types.ErrExecNameNotAllow
}
addrResult := address.ExecAddress(exec)
result := addrResult
return result, nil
}
func getRealExecName(paraName string, name string) string {
if strings.HasPrefix(name, pt.ParaPrefix) {
return name
}
return paraName + name
}
package executor
import (
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common/address"
log "github.com/33cn/chain33/common/log/log15"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
/*
* 执行器相关定义
* 重载基类相关接口
*/
const (
mintPrefix = "evmxgo-mint-"
evmxgoAssetsPrefix = "LODB-evmxgo-assets:"
bridgevmxgoAddrPrefix = "bridgevmxgo-contract-addr"
)
var (
//日志
elog = log.New("module", "evmxgo.executor")
)
var driverName = evmxgotypes.EvmxgoX
type subConfig struct {
SaveTokenTxList bool `json:"saveTokenTxList"`
}
var subCfg subConfig
// Init register dapp
func Init(name string, cfg *types.Chain33Config, sub []byte) {
if sub != nil {
types.MustDecode(sub, &subCfg)
}
drivers.Register(cfg, GetName(), newEvmxgo, cfg.GetDappFork(driverName, "Enable"))
InitExecType()
}
// InitExecType Init Exec Type
func InitExecType() {
ety := types.LoadExecutorType(driverName)
ety.InitFuncList(types.ListMethod(&evmxgo{}))
}
type evmxgo struct {
drivers.DriverBase
}
func newEvmxgo() drivers.Driver {
t := &evmxgo{}
t.SetChild(t)
t.SetExecutorType(types.LoadExecutorType(driverName))
return t
}
// GetName get driver name
func GetName() string {
return newEvmxgo().GetName()
}
func (e *evmxgo) GetDriverName() string {
return driverName
}
// CheckTx 实现自定义检验交易接口,供框架调用
func (e *evmxgo) CheckTx(tx *types.Transaction, index int) error {
// implement code
return nil
}
func (e *evmxgo) getTokens(req *evmxgotypes.ReqEvmxgos) (types.Message, error) {
replyTokens := &evmxgotypes.ReplyEvmxgos{}
tokens, err := e.listTokenKeys(req)
if err != nil {
return nil, err
}
elog.Error("token Query GetTokens", "get count", len(tokens))
for _, t1 := range tokens {
// delete impl by set nil
if len(t1) == 0 {
continue
}
var evmxgoValue evmxgotypes.LocalEvmxgo
err = types.Decode(t1, &evmxgoValue)
if err == nil {
replyTokens.Tokens = append(replyTokens.Tokens, &evmxgoValue)
}
}
//tokenlog.Info("token Query", "replyTokens", replyTokens)
return replyTokens, nil
}
func (e *evmxgo) listTokenKeys(req *evmxgotypes.ReqEvmxgos) ([][]byte, error) {
querydb := e.GetLocalDB()
if req.QueryAll {
keys, err := querydb.List(calcEvmxgoKeyLocal(), nil, 0, 0)
if err != nil && err != types.ErrNotFound {
return nil, err
}
if len(keys) == 0 {
return nil, types.ErrNotFound
}
elog.Debug("token Query GetTokens", "get count", len(keys))
return keys, nil
}
var keys [][]byte
for _, token := range req.Tokens {
keys1, err := querydb.List(calcEvmxgoStatusKeyLocal(token), nil, 0, 0)
if err != nil && err != types.ErrNotFound {
return nil, err
}
keys = append(keys, keys1...)
elog.Debug("token Query GetTokens", "get count", len(keys))
}
if len(keys) == 0 {
return nil, types.ErrNotFound
}
return keys, nil
}
func (e *evmxgo) makeTokenTxKvs(tx *types.Transaction, action *evmxgotypes.EvmxgoAction, receipt *types.ReceiptData, index int, isDel bool) ([]*types.KeyValue, error) {
var kvs []*types.KeyValue
var symbol string
if action.Ty == evmxgotypes.ActionTransfer {
symbol = action.GetTransfer().Cointoken
} else if action.Ty == evmxgotypes.ActionWithdraw {
symbol = action.GetWithdraw().Cointoken
} else if action.Ty == evmxgotypes.EvmxgoActionTransferToExec {
symbol = action.GetTransferToExec().Cointoken
} else {
return kvs, nil
}
kvs, err := tokenTxKvs(tx, symbol, e.GetHeight(), int64(index), isDel)
return kvs, err
}
func (e *evmxgo) getTokenInfo(symbol string) (types.Message, error) {
if symbol == "" {
return nil, types.ErrInvalidParam
}
key := calcEvmxgoStatusKeyLocal(symbol)
values, err := e.GetLocalDB().List(key, nil, 0, 0)
if err != nil {
return nil, err
}
if len(values) == 0 || values[0] == nil || len(values[0]) == 0 {
return nil, types.ErrNotFound
}
var tokenInfo evmxgotypes.LocalEvmxgo
err = types.Decode(values[0], &tokenInfo)
if err != nil {
return &tokenInfo, err
}
return &tokenInfo, nil
}
func (e *evmxgo) getBalance(req *types.ReqBalance) ([]*types.Account, error) {
cfg := e.GetAPI().GetConfig()
accountdb, err := account.NewAccountDB(cfg, evmxgotypes.EvmxgoX, req.GetAssetSymbol(), nil)
if err != nil {
return nil, err
}
switch req.GetExecer() {
case cfg.ExecName(evmxgotypes.EvmxgoX):
queryAddrs := req.GetAddresses()
accounts, err := accountdb.LoadAccounts(e.GetAPI(), queryAddrs)
if err != nil {
log.Error("GetTokenBalance", "err", err.Error(), "token symbol", req.GetAssetSymbol(), "address", queryAddrs)
return nil, err
}
return accounts, nil
default:
execaddress := address.ExecAddress(req.GetExecer())
addrs := req.GetAddresses()
var accounts []*types.Account
for _, addr := range addrs {
acc, err := accountdb.LoadExecAccountQueue(e.GetAPI(), addr, execaddress)
if err != nil {
log.Error("GetTokenBalance for exector", "err", err.Error(), "token symbol", req.GetAssetSymbol(),
"address", addr)
continue
}
accounts = append(accounts, acc)
}
return accounts, nil
}
}
package executor
import (
"encoding/json"
"fmt"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
type evmxgoDB struct {
evmxgo evmxgotypes.Evmxgo
}
func newEvmxgoDB(mint *evmxgotypes.EvmxgoMint) *evmxgoDB {
e := &evmxgoDB{}
e.evmxgo.Symbol = mint.GetSymbol()
return e
}
func (e *evmxgoDB) save(db dbm.KV, key []byte) {
set := e.getKVSet(key)
for i := 0; i < len(set); i++ {
err := db.Set(set[i].GetKey(), set[i].Value)
if err != nil {
panic(err)
}
}
}
func (e *evmxgoDB) getLogs(ty int32, status int32) []*types.ReceiptLog {
var log []*types.ReceiptLog
value := types.Encode(&evmxgotypes.ReceiptEvmxgo{Symbol: e.evmxgo.Symbol})
log = append(log, &types.ReceiptLog{Ty: ty, Log: value})
return log
}
//key:mavl-create-token-addr-xxx or mavl-token-xxx <-----> value:token
func (e *evmxgoDB) getKVSet(key []byte) (kvset []*types.KeyValue) {
value := types.Encode(&e.evmxgo)
kvset = append(kvset, &types.KeyValue{Key: key, Value: value})
return kvset
}
func loadEvmxgoDB(db dbm.KV, symbol string) (*evmxgoDB, error) {
evmxgo, err := db.Get(calcEvmxgoKey(symbol))
if err != nil {
elog.Error("evmxgodb load ", "Can't get token form db for token", symbol)
return nil, evmxgotypes.ErrEvmxgoSymbolNotExist
}
var e evmxgotypes.Evmxgo
err = types.Decode(evmxgo, &e)
if err != nil {
elog.Error("evmxgodb load", "Can't decode token info", symbol)
return nil, err
}
return &evmxgoDB{e}, nil
}
func safeAdd(balance, amount int64) (int64, error) {
if balance+amount < amount || balance+amount > types.MaxTokenBalance {
return balance, types.ErrAmount
}
return balance + amount, nil
}
func (e *evmxgoDB) mint(amount int64) ([]*types.KeyValue, []*types.ReceiptLog, error) {
newTotal, err := safeAdd(e.evmxgo.Total, amount)
if err != nil {
return nil, nil, err
}
prevEvmxgo := e.evmxgo
e.evmxgo.Total = newTotal
kvs := e.getKVSet(calcEvmxgoKey(e.evmxgo.Symbol))
logs := []*types.ReceiptLog{{Ty: evmxgotypes.TyLogEvmxgoMint, Log: types.Encode(&evmxgotypes.ReceiptEvmxgoAmount{Prev: &prevEvmxgo, Current: &e.evmxgo})}}
return kvs, logs, nil
}
func (e *evmxgoDB) burn(db dbm.KV, amount int64) ([]*types.KeyValue, []*types.ReceiptLog, error) {
if e.evmxgo.Total < amount {
return nil, nil, types.ErrNoBalance
}
prevToken := e.evmxgo
e.evmxgo.Total -= amount
kvs := e.getKVSet(calcEvmxgoKey(e.evmxgo.Symbol))
logs := []*types.ReceiptLog{{Ty: evmxgotypes.TyLogEvmxgoBurn, Log: types.Encode(&evmxgotypes.ReceiptEvmxgoAmount{Prev: &prevToken, Current: &e.evmxgo})}}
return kvs, logs, nil
}
type evmxgoAction struct {
coinsAccount *account.DB
db dbm.KV
txhash []byte
fromaddr string
toaddr string
blocktime int64
height int64
execaddr string
api client.QueueProtocolAPI
}
func newEvmxgoAction(e *evmxgo, toaddr string, tx *types.Transaction) *evmxgoAction {
hash := tx.Hash()
fromaddr := tx.From()
return &evmxgoAction{e.GetCoinsAccount(), e.GetStateDB(), hash, fromaddr, toaddr,
e.GetBlockTime(), e.GetHeight(), dapp.ExecAddress(string(tx.Execer)), e.GetAPI()}
}
func getManageKey(key string, db dbm.KV) ([]byte, error) {
manageKey := types.ManageKey(key)
value, err := db.Get([]byte(manageKey))
if err != nil {
elog.Info("evmxgodb", "get db key", "not found manageKey", "key", manageKey)
return getConfigKey(key, db)
}
return value, nil
}
func getConfigKey(key string, db dbm.KV) ([]byte, error) {
configKey := types.ConfigKey(key)
value, err := db.Get([]byte(configKey))
if err != nil {
elog.Info("evmxgodb", "get db key", "not found configKey", "key", configKey)
return nil, err
}
return value, nil
}
func hasConfiged(v1, key string, db dbm.KV) (bool, error) {
value, err := getManageKey(key, db)
if err != nil {
elog.Info("evmxgodb", "get db key", "not found", "key", key)
return false, err
}
if value == nil {
elog.Info("evmxgodb", "get db key", " found nil value", "key", key)
return false, nil
}
var item types.ConfigItem
err = types.Decode(value, &item)
if err != nil {
elog.Error("evmxgodb", "get db key", err)
return false, err // types.ErrBadConfigValue
}
for _, v := range item.GetArr().Value {
if v == v1 {
return true, nil
}
}
return false, nil
}
func loadEvmxgoMintConfig(db dbm.KV, symbol string) (*evmxgotypes.EvmxgoMintConfig, error) {
key := fmt.Sprintf(mintPrefix+"%s", symbol)
value, err := getManageKey(key, db)
if err != nil {
elog.Info("evmxgodb", "get db key", "not found", "key", key)
return nil, err
}
if value == nil {
elog.Info("evmxgodb", "get db key", " found nil value", "key", key)
return nil, nil
}
elog.Info("loadEvmxgoMintConfig", "value", string(value))
var item types.ConfigItem
err = types.Decode(value, &item)
if err != nil {
elog.Error("evmxgodb load loadEvmxgoMintConfig", "Can't decode ConfigItem", symbol)
return nil, err // types.ErrBadConfigValue
}
configValue := item.GetArr().Value
if len(configValue) <= 0 {
return nil, evmxgotypes.ErrEvmxgoSymbolNotConfigValue
}
var e evmxgotypes.EvmxgoMintConfig
err = json.Unmarshal([]byte(configValue[0]), &e)
if err != nil {
elog.Error("evmxgodb load", "Can't decode token info", symbol)
return nil, err
}
return &e, nil
}
func calcTokenAssetsKey(addr string) []byte {
return []byte(fmt.Sprintf(evmxgoAssetsPrefix+"%s", addr))
}
func getTokenAssetsKey(addr string, db dbm.KVDB) (*types.ReplyStrings, error) {
key := calcTokenAssetsKey(addr)
value, err := db.Get(key)
if err != nil && err != types.ErrNotFound {
elog.Error("evmxgodb", "GetTokenAssetsKey", err)
return nil, err
}
var assets types.ReplyStrings
if err == types.ErrNotFound {
return &assets, nil
}
err = types.Decode(value, &assets)
if err != nil {
elog.Error("evmxgodb", "GetTokenAssetsKey", err)
return nil, err
}
return &assets, nil
}
// AddTokenToAssets 添加个人资产列表
func AddTokenToAssets(addr string, db dbm.KVDB, symbol string) []*types.KeyValue {
tokenAssets, err := getTokenAssetsKey(addr, db)
if err != nil {
return nil
}
if tokenAssets == nil {
tokenAssets = &types.ReplyStrings{}
}
var found = false
for _, sym := range tokenAssets.Datas {
if sym == symbol {
found = true
break
}
}
if !found {
tokenAssets.Datas = append(tokenAssets.Datas, symbol)
}
var kv []*types.KeyValue
kv = append(kv, &types.KeyValue{Key: calcTokenAssetsKey(addr), Value: types.Encode(tokenAssets)})
return kv
}
// 铸币不可控, 也是麻烦。 2选1
// 1. 谁可以发起
// 2. 是否需要审核 这个会增加管理的成本
// 现在实现选择 1
func (action *evmxgoAction) mint(mint *evmxgotypes.EvmxgoMint, tx2lock *types.Transaction) (*types.Receipt, error) {
if mint == nil {
return nil, types.ErrInvalidParam
}
if mint.GetAmount() < 0 || mint.GetAmount() > types.MaxTokenBalance || mint.GetSymbol() == "" {
return nil, types.ErrInvalidParam
}
cfg := action.api.GetConfig()
if err := checkMintPara(mint, tx2lock, action.db); nil != err {
return nil, err
}
// TODO check()
evmxgodb, err := loadEvmxgoDB(action.db, mint.GetSymbol())
if err != nil {
if err != evmxgotypes.ErrEvmxgoSymbolNotExist {
return nil, err
}
// evmxgo合约,只要配置了就可以铸币
configSymbol, err := loadEvmxgoMintConfig(action.db, mint.GetSymbol())
if err != nil || configSymbol == nil {
elog.Error("evmxgo mint ", "not config symbol", mint.GetSymbol(), "error", err)
return nil, evmxgotypes.ErrEvmxgoSymbolNotAllowedMint
}
if mint.BridgeToken != configSymbol.Address {
elog.Error("evmxgo mint ", "NotCorrectBridgeTokenAddress with address by manager", configSymbol.Address, "mint.BridgeToken", mint.BridgeToken)
return nil, evmxgotypes.ErrNotCorrectBridgeTokenAddress
}
evmxgodb = newEvmxgoDB(mint)
}
kvs, logs, err := evmxgodb.mint(mint.Amount)
if err != nil {
elog.Error("evmxgo mint ", "symbol", mint.GetSymbol(), "error", err, "from", action.fromaddr)
return nil, err
}
evmxgoAccount, err := account.NewAccountDB(cfg, "evmxgo", mint.GetSymbol(), action.db)
if err != nil {
return nil, err
}
elog.Debug("mint", "evmxgo.Symbol", mint.Symbol, "evmxgo.Amount", mint.Amount)
receipt, err := evmxgoAccount.Mint(mint.Recipient, mint.Amount)
if err != nil {
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
return &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs}, nil
}
func (action *evmxgoAction) burn(burn *evmxgotypes.EvmxgoBurn) (*types.Receipt, error) {
if burn == nil {
return nil, types.ErrInvalidParam
}
if burn.GetAmount() < 0 || burn.GetAmount() > types.MaxTokenBalance || burn.GetSymbol() == "" {
return nil, types.ErrInvalidParam
}
evmxgodb, err := loadEvmxgoDB(action.db, burn.GetSymbol())
if err != nil {
return nil, err
}
kvs, logs, err := evmxgodb.burn(action.db, burn.Amount)
if err != nil {
elog.Error("evmxgo burn ", "symbol", burn.GetSymbol(), "error", err, "from", action.fromaddr)
return nil, err
}
chain33cfg := action.api.GetConfig()
evmxgoAccount, err := account.NewAccountDB(chain33cfg, "evmxgo", burn.GetSymbol(), action.db)
if err != nil {
return nil, err
}
elog.Debug("evmxgo burn", "burn.Symbol", burn.Symbol, "burn.Amount", burn.Amount)
receipt, err := evmxgoAccount.Burn(action.fromaddr, burn.Amount)
if err != nil {
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
return &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs}, nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"fmt"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
tp "github.com/33cn/plugin/plugin/dapp/token/types"
)
const (
evmxgoTxPrefix = "LODB-evmxgo-txHash:"
evmxgoTxAddrPrefix = "LODB-evmxgo-txAddrHash:"
evmxgoTxAddrDirPrefix = "LODB-evmxgo-txAddrDirHash:"
)
func tokenTxKvs(tx *types.Transaction, symbol string, height, index int64, isDel bool) ([]*types.KeyValue, error) {
var kv []*types.KeyValue
from := address.PubKeyToAddress(tx.GetSignature().GetPubkey()).String()
to := tx.GetRealToAddr()
keys := tokenTxkeys(symbol, from, to, height, index)
var txInfo []byte
if !isDel {
txInfo = makeReplyTxInfo(tx, height, index, symbol)
}
for _, k := range keys {
kv = append(kv, &types.KeyValue{Key: k, Value: txInfo})
}
return kv, nil
}
func tokenTxkeys(symbol, from, to string, height, index int64) (result [][]byte) {
key := calcTokenTxKey(symbol, height, index)
result = append(result, key)
if len(from) > 0 {
fromKey1 := calcTokenAddrTxKey(symbol, from, height, index)
fromKey2 := calcTokenAddrTxDirKey(symbol, from, dapp.TxIndexFrom, height, index)
result = append(result, fromKey1)
result = append(result, fromKey2)
}
if len(to) > 0 {
toKey1 := calcTokenAddrTxKey(symbol, to, height, index)
toKey2 := calcTokenAddrTxDirKey(symbol, to, dapp.TxIndexTo, height, index)
result = append(result, toKey1)
result = append(result, toKey2)
}
return
}
// calcTokenTxKey evmxgo transaction entities in local DB
func calcTokenTxKey(symbol string, height, index int64) []byte {
if height == -1 {
return []byte(fmt.Sprintf(evmxgoTxPrefix+"%s:%s", symbol, ""))
}
return []byte(fmt.Sprintf(evmxgoTxPrefix+"%s:%s", symbol, dapp.HeightIndexStr(height, index)))
}
func calcTokenAddrTxKey(symbol, addr string, height, index int64) []byte {
if height == -1 {
return []byte(fmt.Sprintf(evmxgoTxAddrPrefix+"%s:%s:%s", symbol, addr, ""))
}
return []byte(fmt.Sprintf(evmxgoTxAddrPrefix+"%s:%s:%s", symbol, addr, dapp.HeightIndexStr(height, index)))
}
func calcTokenAddrTxDirKey(symbol, addr string, flag int32, height, index int64) []byte {
if height == -1 {
return []byte(fmt.Sprintf(evmxgoTxAddrDirPrefix+"%s:%s:%d:%s", symbol, addr, flag, ""))
}
return []byte(fmt.Sprintf(evmxgoTxAddrDirPrefix+"%s:%s:%d:%s", symbol, addr, flag,
dapp.HeightIndexStr(height, index)))
}
func makeReplyTxInfo(tx *types.Transaction, height, index int64, symbol string) []byte {
var info types.ReplyTxInfo
info.Hash = tx.Hash()
info.Height = height
info.Index = index
info.Assets = []*types.Asset{{Exec: tp.TokenX, Symbol: symbol}}
return types.Encode(&info)
}
package executor
import (
"errors"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
/*
* 实现交易的链上执行接口
* 关键数据上链(statedb)并生成交易回执(log)
*/
func (e *evmxgo) Exec_Transfer(payload *types.AssetsTransfer, tx *types.Transaction, index int) (*types.Receipt, error) {
token := payload.GetCointoken()
cfg := e.GetAPI().GetConfig()
db, err := account.NewAccountDB(cfg, e.GetName(), token, e.GetStateDB())
if err != nil {
return nil, err
}
action := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.ActionTransfer,
Value: &evmxgotypes.EvmxgoAction_Transfer{
Transfer: payload,
},
}
return e.ExecTransWithdraw(db, tx, &action, index)
}
func (e *evmxgo) Exec_Withdraw(payload *types.AssetsWithdraw, tx *types.Transaction, index int) (*types.Receipt, error) {
token := payload.GetCointoken()
cfg := e.GetAPI().GetConfig()
db, err := account.NewAccountDB(cfg, e.GetName(), token, e.GetStateDB())
if err != nil {
return nil, err
}
action := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.ActionWithdraw,
Value: &evmxgotypes.EvmxgoAction_Withdraw{
Withdraw: payload,
},
}
return e.ExecTransWithdraw(db, tx, &action, index)
}
func (e *evmxgo) Exec_TransferToExec(payload *types.AssetsTransferToExec, tx *types.Transaction, index int) (*types.Receipt, error) {
token := payload.GetCointoken()
cfg := e.GetAPI().GetConfig()
db, err := account.NewAccountDB(cfg, e.GetName(), token, e.GetStateDB())
if err != nil {
return nil, err
}
action := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.EvmxgoActionTransferToExec,
Value: &evmxgotypes.EvmxgoAction_TransferToExec{
TransferToExec: payload,
},
}
return e.ExecTransWithdraw(db, tx, &action, index)
}
func (e *evmxgo) Exec_Mint(payload *evmxgotypes.EvmxgoMint, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newEvmxgoAction(e, "", tx)
txGroup, err := e.GetTxGroup(index)
if nil != err {
return nil, err
}
if len(txGroup) < 2 || index == 0 {
return nil, errors.New("Mint tx should be included in lock tx group")
}
txs := e.GetTxs()
return action.mint(payload, txs[index-1])
}
func (e *evmxgo) Exec_Burn(payload *evmxgotypes.EvmxgoBurn, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newEvmxgoAction(e, "", tx)
return action.burn(payload)
}
package executor
import (
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
/*
* 实现区块回退时本地执行的数据清除
*/
// ExecDelLocal localdb kv数据自动回滚接口
func (e *evmxgo) ExecDelLocal(tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
kvs, err := e.DelRollbackKV(tx, tx.Execer)
if err != nil {
return nil, err
}
dbSet := &types.LocalDBSet{}
dbSet.KV = append(dbSet.KV, kvs...)
return dbSet, nil
}
func (e *evmxgo) ExecDelLocal_Transfer(payload *types.AssetsTransfer, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set, err := e.ExecDelLocalLocalTransWithdraw(tx, receiptData, index)
if err != nil {
return nil, err
}
if subCfg.SaveTokenTxList {
action := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.ActionTransfer,
Value: &evmxgotypes.EvmxgoAction_Transfer{
Transfer: payload,
},
}
kvs, err := e.makeTokenTxKvs(tx, &action, receiptData, index, true)
if err != nil {
return nil, err
}
set.KV = append(set.KV, kvs...)
}
return set, nil
}
func (e *evmxgo) ExecDelLocal_Withdraw(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set, err := e.ExecDelLocalLocalTransWithdraw(tx, receiptData, index)
if err != nil {
return nil, err
}
if subCfg.SaveTokenTxList {
tokenAction := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.ActionWithdraw,
Value: &evmxgotypes.EvmxgoAction_Withdraw{
Withdraw: payload,
},
}
kvs, err := e.makeTokenTxKvs(tx, &tokenAction, receiptData, index, true)
if err != nil {
return nil, err
}
set.KV = append(set.KV, kvs...)
}
return set, nil
}
func (e *evmxgo) ExecDelLocal_TransferToExec(payload *types.AssetsTransferToExec, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set, err := e.ExecDelLocalLocalTransWithdraw(tx, receiptData, index)
if err != nil {
return nil, err
}
if subCfg.SaveTokenTxList {
tokenAction := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.EvmxgoActionTransferToExec,
Value: &evmxgotypes.EvmxgoAction_TransferToExec{
TransferToExec: payload,
},
}
kvs, err := e.makeTokenTxKvs(tx, &tokenAction, receiptData, index, true)
if err != nil {
return nil, err
}
set.KV = append(set.KV, kvs...)
}
return set, nil
}
func resetMint(e *evmxgotypes.LocalEvmxgo, height, time, amount int64) *evmxgotypes.LocalEvmxgo {
e.Total = e.Total - amount
return e
}
func resetBurn(e *evmxgotypes.LocalEvmxgo, height, time, amount int64) *evmxgotypes.LocalEvmxgo {
e.Total = e.Total + amount
return e
}
func (e *evmxgo) ExecDelLocal_Mint(payload *evmxgotypes.EvmxgoMint, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
localToken, err := loadLocalToken(payload.Symbol, e.GetLocalDB())
if err != nil {
return nil, err
}
localToken = resetMint(localToken, e.GetHeight(), e.GetBlockTime(), payload.Amount)
key := calcEvmxgoStatusKeyLocal(payload.Symbol)
var set []*types.KeyValue
set = append(set, &types.KeyValue{Key: key, Value: types.Encode(localToken)})
table := NewLogsTable(e.GetLocalDB())
txIndex := dapp.HeightIndexStr(e.GetHeight(), int64(index))
err = table.Del([]byte(txIndex))
if err != nil {
return nil, err
}
kv, err := table.Save()
if err != nil {
return nil, err
}
set = append(set, kv...)
return &types.LocalDBSet{KV: set}, nil
}
func (e *evmxgo) ExecDelLocal_Burn(payload *evmxgotypes.EvmxgoBurn, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
localToken, err := loadLocalToken(payload.Symbol, e.GetLocalDB())
if err != nil {
return nil, err
}
localToken = resetBurn(localToken, e.GetHeight(), e.GetBlockTime(), payload.Amount)
key := calcEvmxgoStatusKeyLocal(payload.Symbol)
var set []*types.KeyValue
set = append(set, &types.KeyValue{Key: key, Value: types.Encode(localToken)})
table := NewLogsTable(e.GetLocalDB())
txIndex := dapp.HeightIndexStr(e.GetHeight(), int64(index))
err = table.Del([]byte(txIndex))
if err != nil {
return nil, err
}
kv, err := table.Save()
if err != nil {
return nil, err
}
set = append(set, kv...)
return &types.LocalDBSet{KV: set}, nil
}
package executor
import (
"encoding/hex"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
/*
* 实现交易相关数据本地执行,数据不上链
* 非关键数据,本地存储(localDB), 用于辅助查询,效率高
*/
func (e *evmxgo) ExecLocal_Transfer(payload *types.AssetsTransfer, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set, err := e.ExecLocalTransWithdraw(tx, receiptData, index)
if err != nil {
return nil, err
}
// 添加个人资产列表
kv := AddTokenToAssets(payload.To, e.GetLocalDB(), payload.Cointoken)
if kv != nil {
set.KV = append(set.KV, kv...)
}
if subCfg.SaveTokenTxList {
evmxgoAction := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.ActionTransfer,
Value: &evmxgotypes.EvmxgoAction_Transfer{
Transfer: payload,
},
}
kvs, err := e.makeTokenTxKvs(tx, &evmxgoAction, receiptData, index, false)
if err != nil {
return nil, err
}
set.KV = append(set.KV, kvs...)
}
return set, nil
}
func (e *evmxgo) ExecLocal_Withdraw(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set, err := e.ExecLocalTransWithdraw(tx, receiptData, index)
if err != nil {
return nil, err
}
// 添加个人资产列表
kv := AddTokenToAssets(tx.From(), e.GetLocalDB(), payload.Cointoken)
if kv != nil {
set.KV = append(set.KV, kv...)
}
if subCfg.SaveTokenTxList {
evmxgoAction := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.ActionWithdraw,
Value: &evmxgotypes.EvmxgoAction_Withdraw{
Withdraw: payload,
},
}
kvs, err := e.makeTokenTxKvs(tx, &evmxgoAction, receiptData, index, false)
if err != nil {
return nil, err
}
set.KV = append(set.KV, kvs...)
}
return set, nil
}
func (e *evmxgo) ExecLocal_TransferToExec(payload *types.AssetsTransferToExec, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set, err := e.ExecLocalTransWithdraw(tx, receiptData, index)
if err != nil {
return nil, err
}
if subCfg.SaveTokenTxList {
evmxgoAction := evmxgotypes.EvmxgoAction{
Ty: evmxgotypes.EvmxgoActionTransferToExec,
Value: &evmxgotypes.EvmxgoAction_TransferToExec{
TransferToExec: payload,
},
}
kvs, err := e.makeTokenTxKvs(tx, &evmxgoAction, receiptData, index, false)
if err != nil {
return nil, err
}
set.KV = append(set.KV, kvs...)
}
return set, nil
}
func loadLocalToken(symbol string, db db.KVDB) (*evmxgotypes.LocalEvmxgo, error) {
key := calcEvmxgoStatusKeyLocal(symbol)
v, err := db.Get(key)
if err != nil {
return nil, evmxgotypes.ErrEvmxgoSymbolNotExist
}
var localToken evmxgotypes.LocalEvmxgo
err = types.Decode(v, &localToken)
if err != nil {
return nil, err
}
return &localToken, nil
}
func newLocalEvmxgo(mint *evmxgotypes.EvmxgoMint) *evmxgotypes.LocalEvmxgo {
e := evmxgotypes.LocalEvmxgo{}
e.Symbol = mint.GetSymbol()
return &e
}
func setMint(t *evmxgotypes.LocalEvmxgo, height, time, amount int64) *evmxgotypes.LocalEvmxgo {
t.Total = t.Total + amount
return t
}
func setBurn(t *evmxgotypes.LocalEvmxgo, height, time, amount int64) *evmxgotypes.LocalEvmxgo {
t.Total = t.Total - amount
return t
}
func (e *evmxgo) ExecLocal_Mint(payload *evmxgotypes.EvmxgoMint, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
localToken, err := loadLocalToken(payload.Symbol, e.GetLocalDB())
if err != nil && err != evmxgotypes.ErrEvmxgoSymbolNotExist {
return nil, err
}
// evmxgo合约,只要配置了就可以铸币
if err == evmxgotypes.ErrEvmxgoSymbolNotExist {
configSynbol, err := loadEvmxgoMintConfig(e.GetStateDB(), payload.GetSymbol())
if err != nil || configSynbol == nil {
elog.Error("evmxgo mint ", "not config symbol", payload.GetSymbol(), "error", err)
return nil, evmxgotypes.ErrEvmxgoSymbolNotAllowedMint
}
localToken = newLocalEvmxgo(payload)
localToken.Introduction = configSynbol.Introduction
localToken.Precision = configSynbol.Precision
}
localToken = setMint(localToken, e.GetHeight(), e.GetBlockTime(), payload.Amount)
var set []*types.KeyValue
key := calcEvmxgoStatusKeyLocal(payload.Symbol)
set = append(set, &types.KeyValue{Key: key, Value: types.Encode(localToken)})
table := NewLogsTable(e.GetLocalDB())
txIndex := dapp.HeightIndexStr(e.GetHeight(), int64(index))
err = table.Add(&evmxgotypes.LocalEvmxgoLogs{Symbol: payload.Symbol, TxIndex: txIndex, ActionType: evmxgotypes.EvmxgoActionMint, TxHash: "0x" + hex.EncodeToString(tx.Hash())})
if err != nil {
return nil, err
}
kv, err := table.Save()
if err != nil {
return nil, err
}
set = append(set, kv...)
return &types.LocalDBSet{KV: set}, nil
}
func (e *evmxgo) ExecLocal_Burn(payload *evmxgotypes.EvmxgoBurn, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
localToken, err := loadLocalToken(payload.Symbol, e.GetLocalDB())
if err != nil {
return nil, err
}
localToken = setBurn(localToken, e.GetHeight(), e.GetBlockTime(), payload.Amount)
var set []*types.KeyValue
key := calcEvmxgoStatusKeyLocal(payload.Symbol)
set = append(set, &types.KeyValue{Key: key, Value: types.Encode(localToken)})
table := NewLogsTable(e.GetLocalDB())
txIndex := dapp.HeightIndexStr(e.GetHeight(), int64(index))
err = table.Add(&evmxgotypes.LocalEvmxgoLogs{Symbol: payload.Symbol, TxIndex: txIndex, ActionType: evmxgotypes.EvmxgoActionBurn, TxHash: "0x" + hex.EncodeToString(tx.Hash())})
if err != nil {
return nil, err
}
kv, err := table.Save()
if err != nil {
return nil, err
}
set = append(set, kv...)
return &types.LocalDBSet{KV: set}, nil
}
//当区块回滚时,框架支持自动回滚localdb kv,需要对exec-local返回的kv进行封装
func (e *evmxgo) addAutoRollBack(tx *types.Transaction, kv []*types.KeyValue) *types.LocalDBSet {
dbSet := &types.LocalDBSet{}
dbSet.KV = e.AddRollbackKV(tx, tx.Execer, kv)
return dbSet
}
package executor
import (
"context"
"errors"
"fmt"
"math/rand"
"testing"
"time"
"github.com/33cn/chain33/account"
apimock "github.com/33cn/chain33/client/mocks"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/util"
bridgevmxgo "github.com/33cn/plugin/plugin/dapp/bridgevmxgo/contracts/generated"
"github.com/stretchr/testify/mock"
"strings"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/types"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
pty "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc"
)
var (
isMainNetTest bool
isParaNetTest bool
)
var (
mainNetgrpcAddr = "localhost:8802"
ParaNetgrpcAddr = "localhost:8902"
mainClient types.Chain33Client
paraClient types.Chain33Client
r *rand.Rand
ErrTest = errors.New("ErrTest")
addrexec string
manageaddrexec string
privkey crypto.PrivKey
privkeySupper crypto.PrivKey
)
const (
//defaultAmount = 1e10
fee = 1e6
)
var (
burnAmount int64 = 200
execName = "evmxgo"
transExecName = "token"
mananerexecName = "manage"
transToAddr = "17EVv6tW2HzE73TVB6YXQYThQJxa7kuZb8"
transAmount int64 = 100
walletPass = "test1234"
)
var (
Symbol = "TEST"
AssetExecPara = "paracross"
PrivKeyA = "0x4dcb00c7d01a3d377c0d5a14cd7ec91798a74c8b41896c5d21fc8b9bf4b40e42" // 1jQtMFpmEW2J4fgEG3opEoVzfSyMpBMaR
PrivKeyB = "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" // 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
PrivKeyC = "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" // 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k
PrivKeyD = "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" // 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
Nodes = [][]byte{
[]byte("1jQtMFpmEW2J4fgEG3opEoVzfSyMpBMaR"),
[]byte("1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"),
[]byte("1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"),
[]byte("1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"),
}
)
var (
contractAddr = "1AdSxpZKKbdaFNuydxvGktBtUYHmcuP6C5"
lockAmt int64 = 2000
bridgeToken = string(Nodes[0])
recipient = string(Nodes[0])
// DefaultFeeRate 默认手续费率
DefaultFeeRate int64 = 100000
)
const BridgeBankABIBridgevmxgo = "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_operatorAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oracleAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_goAssetBridgeAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_beneficiary\",\"type\":\"address\"}],\"name\":\"LogBridgeTokenMint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_ownerFrom\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_goAssetReceiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"LogGoAssetTokenBurn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"LogLock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"LogNewBridgeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"LogUnlock\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"addToken2LockList\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"bridgeTokenCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"bridgeTokenCreated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridgeTokenWhitelist\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_goAssetReceiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_goAssetTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"burnBridgeTokens\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_percents\",\"type\":\"uint8\"}],\"name\":\"configLockedTokenOfflineSave\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_offlineSave\",\"type\":\"address\"}],\"name\":\"configOfflineSaveAccount\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createNewBridgeToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_id\",\"type\":\"bytes32\"}],\"name\":\"getGoAssetDepositStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"getLockedTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"getToken2address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"getofflineSaveCfg\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"goAssetBridge\",\"outputs\":[{\"internalType\":\"contractGoAssetBridge\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"hasBridgeTokenCreated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"highThreshold\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"lock\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lockNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"lockedFunds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lowThreshold\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_goAssetSender\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"_intendedRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bridgeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mintBridgeTokens\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"offlineSave\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"offlineSaveCfgs\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"_percents\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"operator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contractOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"token2address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"tokenAllow2Lock\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unlock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_id\",\"type\":\"bytes32\"}],\"name\":\"viewGoAssetDeposit\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]"
type execEnv struct {
blockTime int64
blockHeight int64
difficulty uint64
}
func (e *execEnv) incr() {
e.blockTime += 1
e.blockHeight += 1
}
func init() {
fmt.Println("Init start")
defer fmt.Println("Init end")
isMainNetTest = true
if !isMainNetTest && !isParaNetTest {
return
}
conn, err := grpc.Dial(mainNetgrpcAddr, grpc.WithInsecure())
if err != nil {
panic(err)
}
mainClient = types.NewChain33Client(conn)
conn, err = grpc.Dial(ParaNetgrpcAddr, grpc.WithInsecure())
if err != nil {
panic(err)
}
paraClient = types.NewChain33Client(conn)
r = rand.New(rand.NewSource(time.Now().UnixNano()))
addrexec = address.ExecAddress("")
manageaddrexec = address.ExecAddress("manage")
privkey = getprivkey(PrivKeyA)
privkeySupper = getprivkey(PrivKeyA)
}
func getprivkey(key string) crypto.PrivKey {
cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil {
panic(err)
}
bkey, err := common.FromHex(key)
if err != nil {
panic(err)
}
priv, err := cr.PrivKeyFromBytes(bkey)
if err != nil {
panic(err)
}
return priv
}
func genaddress() (string, crypto.PrivKey) {
cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil {
panic(err)
}
privto, err := cr.GenKey()
if err != nil {
panic(err)
}
addrto := address.PubKeyToAddress(privto.PubKey().Bytes())
fmt.Println("addr:", addrto.String())
fmt.Println(bridgevmxgo.BridgeBankBin)
return addrto.String(), privto
}
func waitTx(hash []byte) bool {
i := 0
for {
i++
if i%100 == 0 {
fmt.Println("wait transaction timeout")
return false
}
var reqHash types.ReqHash
reqHash.Hash = hash
res, err := mainClient.QueryTransaction(context.Background(), &reqHash)
if err != nil {
time.Sleep(time.Second)
}
if res != nil {
return true
}
}
}
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1
c, err := crypto.Load(types.GetSignName(pty.EvmxgoX, signType), -1)
if err != nil {
return tx, err
}
bytes, err := common.FromHex(hexPrivKey[:])
if err != nil {
return tx, err
}
privKey, err := c.PrivKeyFromBytes(bytes)
if err != nil {
return tx, err
}
tx.Sign(int32(signType), privKey)
return tx, nil
}
func Test_Token(t *testing.T) {
cfg := types.NewChain33Config(strings.Replace(types.GetDefaultCfgstring(), "Title=\"local\"", "Title=\"chain33\"", 1))
Init(pty.EvmxgoX, cfg, nil)
total := int64(100000)
accountA := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[0]),
}
accountB := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[1]),
}
execAddr := address.ExecAddress(pty.EvmxgoX)
stateDB, _ := dbm.NewGoMemDB("1", "2", 100)
_, _, kvdb := util.CreateTestDB()
accA, _ := account.NewAccountDB(cfg, pty.EvmxgoX, Symbol, stateDB)
accA.SaveExecAccount(execAddr, &accountA)
accB, _ := account.NewAccountDB(cfg, AssetExecPara, Symbol, stateDB)
accB.SaveExecAccount(execAddr, &accountB)
env := &execEnv{
10,
0,
1539918074,
}
// set config key
item := &types.ConfigItem{
Key: fmt.Sprintf("mavl-manage-evmxgo-mint-%s", Symbol),
Value: &types.ConfigItem_Arr{
Arr: &types.ArrayConfig{Value: []string{fmt.Sprintf("{\"address\":\"%s\",\"precision\":4,\"introduction\":\"介绍\"}", bridgeToken)}},
},
}
stateDB.Set([]byte(item.Key), types.Encode(item))
itemBridgevmxgoConfig := &types.ConfigItem{
Key: "mavl-manage-bridgevmxgo-contract-addr",
Value: &types.ConfigItem_Arr{
Arr: &types.ArrayConfig{Value: []string{fmt.Sprintf("{\"address\":\"%s\"}", contractAddr)}},
},
}
stateDB.Set([]byte(itemBridgevmxgoConfig.Key), types.Encode(itemBridgevmxgoConfig))
exec := newEvmxgo()
api := new(apimock.QueueProtocolAPI)
api.On("GetConfig", mock.Anything).Return(cfg, nil)
exec.SetAPI(api)
exec.SetStateDB(stateDB)
exec.SetLocalDB(kvdb)
receipt, err := evmxgo_Exec_Mint(exec, env)
assert.Nil(t, err)
assert.NotNil(t, receipt)
//t.Log(receipt)
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
accCheck := accA.LoadAccount(recipient)
assert.Equal(t, lockAmt, accCheck.Balance)
set, err := evmxgo_Exec_Mint_Local(exec, receipt)
assert.Nil(t, err)
assert.NotNil(t, set)
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
env.incr()
receipt, err = evmxgo_Exec_Transfer(exec, env)
assert.Nil(t, err)
assert.NotNil(t, receipt)
//t.Log(receipt)
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
set, err = evmxgo_Exec_Transfer_Local(exec, receipt)
assert.Nil(t, err)
assert.NotNil(t, set)
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
env.incr()
receipt, err = evmxgo_Exec_Transfer_Exec(exec, env)
assert.Nil(t, err)
assert.NotNil(t, receipt)
//t.Log(receipt)
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
set, err = evmxgo_Exec_Transfer_Exec_Local(exec, receipt)
assert.Nil(t, err)
assert.NotNil(t, set)
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
env.incr()
receipt, err = evmxgo_Exec_Withdraw(exec, env)
assert.Nil(t, err)
assert.NotNil(t, receipt)
//t.Log(receipt)
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
set, err = evmxgo_Exec_Withdraw_Local(exec, receipt)
assert.Nil(t, err)
assert.NotNil(t, set)
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
env.incr()
receipt, err = evmxgo_Exec_Burn(exec, env)
assert.Nil(t, err)
assert.NotNil(t, receipt)
//t.Log(receipt)
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
set, err = evmxgo_Exec_Burn_Local(exec, receipt)
assert.Nil(t, err)
assert.NotNil(t, set)
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
}
func evmxgo_Exec_Mint(exec dapp.Driver, env *execEnv) (*types.Receipt, error) {
// evmxgo mint
// lock
parameter := fmt.Sprintf("lock(%s, %s, %d)", recipient, bridgeToken, lockAmt)
_, packData, err := evmAbi.Pack(parameter, BridgeBankABIBridgevmxgo, false)
if nil != err {
fmt.Println("evmAbi.Pack", "Failed to do abi.Pack: ", err.Error())
return nil, ErrTest
}
evmAction := &evmtypes.EVMContractAction{
Amount: 0,
GasLimit: 0,
GasPrice: 0,
Para: packData,
Note: "",
ContractAddr: contractAddr,
}
evmTx := &types.Transaction{Execer: []byte(evmtypes.ExecutorName), Payload: types.Encode(evmAction), Fee: fee}
evmTx.Nonce = r.Int63()
// 创建
pMint := &pty.EvmxgoMint{
Symbol: Symbol,
Amount: lockAmt,
BridgeToken: bridgeToken,
Recipient: recipient,
}
createTxMint, err := types.CallCreateTransaction(pty.EvmxgoX, "Mint", pMint)
if err != nil {
fmt.Println("RPC_Default_Process", "err", err)
}
txGroup := []*types.Transaction{evmTx, createTxMint}
createTx, err := types.CreateTxGroup(txGroup, DefaultFeeRate)
if err != nil {
fmt.Println("RPC_Default_Process", "err", err)
}
_ = createTx.SignN(0, 1, privkey)
_ = createTx.SignN(1, 1, privkey)
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
value, ok := exec.(*evmxgo)
if !ok {
fmt.Println("type error")
return nil, ErrTest
}
value.SetTxs(txGroup)
receipt, err := value.Exec_Mint(pMint, createTx.Tx(), 1)
return receipt, err
}
func evmxgo_Exec_Mint_Local(exec dapp.Driver, receipt *types.Receipt) (*types.LocalDBSet, error) {
pMint := &pty.EvmxgoMint{
Symbol: Symbol,
Amount: lockAmt,
BridgeToken: bridgeToken,
Recipient: recipient,
}
createTxMint, err := types.CallCreateTransaction(pty.EvmxgoX, "Mint", pMint)
if err != nil {
fmt.Println("RPC_Default_Process", "err", err)
return nil, err
}
receiptDate := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
return exec.ExecLocal(createTxMint, receiptDate, int(1))
}
func evmxgo_Exec_Transfer(exec dapp.Driver, env *execEnv) (*types.Receipt, error) {
v := &pty.EvmxgoAction_Transfer{Transfer: &types.AssetsTransfer{Cointoken: Symbol, Amount: transAmount, Note: []byte(""), To: transToAddr}}
transfer := &pty.EvmxgoAction{Value: v, Ty: pty.ActionTransfer}
tx := &types.Transaction{Execer: []byte(execName), Payload: types.Encode(transfer), Fee: fee, To: addrexec}
tx.Nonce = r.Int63()
Tx1, err := signTx(tx, PrivKeyA)
if err != nil {
fmt.Println("RPC_Default_Process sign", "err", err)
return nil, err
}
exec.SetEnv(env.blockHeight+1, env.blockTime+1, env.difficulty)
return exec.Exec(Tx1, int(1))
}
func evmxgo_Exec_Transfer_Local(exec dapp.Driver, receipt *types.Receipt) (*types.LocalDBSet, error) {
v := &pty.EvmxgoAction_Transfer{Transfer: &types.AssetsTransfer{Cointoken: Symbol, Amount: transAmount, Note: []byte(""), To: transToAddr}}
transfer := &pty.EvmxgoAction{Value: v, Ty: pty.ActionTransfer}
tx := &types.Transaction{Execer: []byte(execName), Payload: types.Encode(transfer), Fee: fee, To: addrexec}
tx.Nonce = r.Int63()
Tx1, err := signTx(tx, PrivKeyA)
if err != nil {
fmt.Println("RPC_Default_Process sign", "err", err)
return nil, err
}
receiptDate := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
return exec.ExecLocal(Tx1, receiptDate, int(1))
}
func evmxgo_Exec_Transfer_Exec(exec dapp.Driver, env *execEnv) (*types.Receipt, error) {
v := &pty.EvmxgoAction_TransferToExec{TransferToExec: &types.AssetsTransferToExec{
Cointoken: Symbol,
Amount: transAmount,
Note: []byte(""),
ExecName: transExecName,
To: address.ExecAddress(transExecName)},
}
transfer := &pty.EvmxgoAction{Value: v, Ty: pty.EvmxgoActionTransferToExec}
tx := &types.Transaction{Execer: []byte(execName), Payload: types.Encode(transfer), Fee: fee, To: addrexec}
tx.Nonce = r.Int63()
Tx1, err := signTx(tx, PrivKeyA)
if err != nil {
fmt.Println("RPC_Default_Process sign", "err", err)
}
exec.SetEnv(env.blockHeight+1, env.blockTime+1, env.difficulty)
return exec.Exec(Tx1, int(1))
}
func evmxgo_Exec_Transfer_Exec_Local(exec dapp.Driver, receipt *types.Receipt) (*types.LocalDBSet, error) {
v := &pty.EvmxgoAction_TransferToExec{TransferToExec: &types.AssetsTransferToExec{
Cointoken: Symbol,
Amount: transAmount,
Note: []byte(""),
ExecName: transExecName,
To: address.ExecAddress(transExecName)},
}
transfer := &pty.EvmxgoAction{Value: v, Ty: pty.EvmxgoActionTransferToExec}
tx := &types.Transaction{Execer: []byte(execName), Payload: types.Encode(transfer), Fee: fee, To: addrexec}
tx.Nonce = r.Int63()
Tx1, err := signTx(tx, PrivKeyA)
if err != nil {
fmt.Println("RPC_Default_Process sign", "err", err)
return nil, err
}
receiptDate := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
return exec.ExecLocal(Tx1, receiptDate, int(1))
}
func evmxgo_Exec_Withdraw(exec dapp.Driver, env *execEnv) (*types.Receipt, error) {
v := &pty.EvmxgoAction_Withdraw{Withdraw: &types.AssetsWithdraw{
Cointoken: Symbol,
Amount: transAmount,
Note: []byte(""),
ExecName: transExecName,
To: address.ExecAddress(transExecName)},
}
transfer := &pty.EvmxgoAction{Value: v, Ty: pty.ActionWithdraw}
tx := &types.Transaction{Execer: []byte(execName), Payload: types.Encode(transfer), Fee: fee, To: addrexec}
tx.Nonce = r.Int63()
Tx1, err := signTx(tx, PrivKeyA)
if err != nil {
fmt.Println("RPC_Default_Process sign", "err", err)
}
exec.SetEnv(env.blockHeight+1, env.blockTime+1, env.difficulty)
return exec.Exec(Tx1, int(1))
}
func evmxgo_Exec_Withdraw_Local(exec dapp.Driver, receipt *types.Receipt) (*types.LocalDBSet, error) {
v := &pty.EvmxgoAction_Withdraw{Withdraw: &types.AssetsWithdraw{
Cointoken: Symbol,
Amount: transAmount,
Note: []byte(""),
ExecName: transExecName,
To: address.ExecAddress(transExecName)},
}
transfer := &pty.EvmxgoAction{Value: v, Ty: pty.ActionWithdraw}
tx := &types.Transaction{Execer: []byte(execName), Payload: types.Encode(transfer), Fee: fee, To: addrexec}
tx.Nonce = r.Int63()
Tx1, err := signTx(tx, PrivKeyA)
if err != nil {
fmt.Println("RPC_Default_Process sign", "err", err)
return nil, err
}
receiptDate := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
return exec.ExecLocal(Tx1, receiptDate, int(1))
}
func evmxgo_Exec_Burn(exec dapp.Driver, env *execEnv) (*types.Receipt, error) {
p4 := &pty.EvmxgoBurn{
Symbol: Symbol,
Amount: burnAmount,
}
tx, err := types.CallCreateTransaction(pty.EvmxgoX, "Burn", p4)
if err != nil {
fmt.Println("RPC_Default_Process CallCreateTransaction", "err", err)
return nil, err
}
Tx1, err := signTx(tx, PrivKeyA)
if err != nil {
fmt.Println("RPC_Default_Process sign", "err", err)
}
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
return exec.Exec(Tx1, int(1))
}
func evmxgo_Exec_Burn_Local(exec dapp.Driver, receipt *types.Receipt) (*types.LocalDBSet, error) {
p4 := &pty.EvmxgoBurn{
Symbol: Symbol,
Amount: burnAmount,
}
tx, err := types.CallCreateTransaction(pty.EvmxgoX, "Burn", p4)
if err != nil {
fmt.Println("RPC_Default_Process CallCreateTransaction", "err", err)
return nil, err
}
Tx1, err := signTx(tx, PrivKeyA)
if err != nil {
fmt.Println("RPC_Default_Process sign test", "err", err)
return nil, err
}
receiptDate := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
return exec.ExecLocal(Tx1, receiptDate, int(1))
}
package executor
import "fmt"
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
var (
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB = "mavl-evmxgo-statedb"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB = "LODB-evmxgo-"
evmxgoCreatedSTONewLocal = "LODB-evmxgo-create-sto-"
)
func calcEvmxgoKey(value string) (key []byte) {
return []byte(fmt.Sprintf(KeyPrefixStateDB+"-%s", value))
}
func calcEvmxgoKeyLocal() []byte {
return []byte(evmxgoCreatedSTONewLocal)
}
func calcEvmxgoStatusKeyLocal(token string) []byte {
return []byte(fmt.Sprintf(evmxgoCreatedSTONewLocal+"%s", token))
}
//存储地址上收币的信息
func calcAddrKey(token string, addr string) []byte {
return []byte(fmt.Sprintf("LODB-evmxgo-%s-Addr:%s", token, addr))
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
// 记录token 的更改记录,
// 包含创建完成, 铸币, 以后可能包含燃烧等
import (
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
var opt_logs_table = &table.Option{
Prefix: "LODB-evmxgo",
Name: "logs",
Primary: "txIndex",
Index: []string{
"symbol",
},
}
// LogsRow row
type LogsRow struct {
*evmxgotypes.LocalEvmxgoLogs
}
// NewOrderRow create row
func NewOrderRow() *LogsRow {
return &LogsRow{LocalEvmxgoLogs: nil}
}
// CreateRow create row
func (r *LogsRow) CreateRow() *table.Row {
return &table.Row{Data: &evmxgotypes.LocalEvmxgoLogs{}}
}
// SetPayload set payload
func (r *LogsRow) SetPayload(data types.Message) error {
if d, ok := data.(*evmxgotypes.LocalEvmxgoLogs); ok {
r.LocalEvmxgoLogs = d
return nil
}
return types.ErrTypeAsset
}
// Get get index key
func (r *LogsRow) Get(key string) ([]byte, error) {
switch key {
case "txIndex":
return []byte(r.TxIndex), nil
case "symbol":
return []byte(r.Symbol), nil
default:
return nil, types.ErrNotFound
}
}
// NewLogsTable create table
func NewLogsTable(kvdb dbm.KV) *table.Table {
rowMeta := NewOrderRow()
err := rowMeta.SetPayload(&evmxgotypes.LocalEvmxgoLogs{})
if err != nil {
panic(err)
}
t, err := table.NewTable(rowMeta, kvdb, opt_logs_table)
if err != nil {
panic(err)
}
return t
}
func list(db dbm.KVDB, indexName string, data *evmxgotypes.LocalEvmxgoLogs, count, direction int32) ([]*table.Row, error) {
query := NewLogsTable(db).GetQuery(db)
var primary []byte
if len(data.TxIndex) > 0 {
primary = []byte(data.TxIndex)
}
cur := &LogsRow{LocalEvmxgoLogs: data}
index, err := cur.Get(indexName)
if err != nil {
elog.Error("query List failed", "key", string(primary), "param", data, "err", err)
return nil, err
}
elog.Debug("query List dbg", "indexName", indexName, "index", string(index), "primary", primary, "count", count, "direction", direction)
rows, err := query.ListIndex(indexName, index, primary, count, direction)
if err != nil {
elog.Error("query List failed", "key", string(primary), "param", data, "err", err)
return nil, err
}
if len(rows) == 0 {
return nil, types.ErrNotFound
}
return rows, nil
}
package executor
import (
"encoding/json"
"errors"
"math/big"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
bridgevmxgo "github.com/33cn/plugin/plugin/dapp/bridgevmxgo/contracts/generated"
chain33Abi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
const (
LockMethod = "lock"
)
//solidity interface: function lock(address _recipient, address _token, uint256 _amount)
//铸币交易的接收人必须与发起lock交易时填写的接收地址一致
func checkMintPara(mint *evmxgotypes.EvmxgoMint, tx2lock *types.Transaction, db dbm.KV) error {
bridgevmxgoConfig, err := loadBridgevmxgoAddr(db)
if nil != err {
return err
}
var action evmtypes.EVMContractAction
if err := types.Decode(tx2lock.Payload, &action); nil != err {
return err
}
//确认合约地址的正确性
if action.ContractAddr != bridgevmxgoConfig.Address {
return errors.New("Not consistent bridgevmxgo address configured by manager")
}
unpack, err := chain33Abi.UnpackAllTypes(action.Para, LockMethod, bridgevmxgo.BridgeBankABI)
if err != nil {
return err
}
var recipient, bridgeToken string
var amount int64
correct := 0
for _, para := range unpack {
switch para.Name {
case "_recipient":
recipient = para.Value.(string)
if mint.Recipient != recipient {
return errors.New("Not consitent recipient address")
}
correct++
case "_amount":
amount = para.Value.(*big.Int).Int64()
if mint.Amount != amount {
return errors.New("Not consitent Amount")
}
correct++
case "_token":
bridgeToken = para.Value.(string)
if mint.BridgeToken != bridgeToken {
return errors.New("Not consitent token Address")
}
correct++
}
}
elog.Info("checkMintPara", "lock parameter unpacked _recipient ", recipient, "bridgeToken", bridgeToken,
"amount", amount)
if correct != 3 {
return errors.New("not check all the points: _recipient, _amount, _token")
}
return nil
}
func loadBridgevmxgoAddr(db dbm.KV) (*evmxgotypes.BridgevmxgoConfig, error) {
key := bridgevmxgoAddrPrefix
value, err := getManageKey(key, db)
if err != nil {
elog.Info("loadBridgevmxgoAddr", "get db key", "not found", "key", key)
return nil, err
}
if value == nil {
elog.Info("loadBridgevmxgoAddr", "get db key", " found nil value", "key", key)
return nil, nil
}
elog.Info("loadBridgevmxgoAddr", "value", string(value))
var item types.ConfigItem
err = types.Decode(value, &item)
if err != nil {
elog.Error("loadBridgevmxgoAddr load loadEvmxgoMintConfig", "Can't decode ConfigItem due to", err.Error())
return nil, err // types.ErrBadConfigValue
}
configValue := item.GetArr().Value
if len(configValue) <= 0 {
return nil, evmxgotypes.ErrEvmxgoSymbolNotConfigValue
}
var e evmxgotypes.BridgevmxgoConfig
err = json.Unmarshal([]byte(configValue[0]), &e)
if err != nil {
elog.Error("loadBridgevmxgoAddr load", "Can't decode token info due to:", err.Error())
return nil, err
}
return &e, nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
// Query_GetTokens 获取evmxgo合约里面的币
func (e *evmxgo) Query_GetTokens(in *evmxgotypes.ReqEvmxgos) (types.Message, error) {
if in == nil {
return nil, types.ErrInvalidParam
}
return e.getTokens(in)
}
// Query_GetTokenInfo 获取evmxgo合约里指定的币
func (e *evmxgo) Query_GetTokenInfo(in *types.ReqString) (types.Message, error) {
if in == nil {
return nil, types.ErrInvalidParam
}
return e.getTokenInfo(in.GetData())
}
// Query_GetBalance 获取evmxgo合约里指定地址的币
func (e *evmxgo) Query_GetBalance(in *types.ReqBalance) (types.Message, error) {
if in == nil {
return nil, types.ErrInvalidParam
}
accounts, err := e.getBalance(in)
if err != nil {
return nil, err
}
reply := evmxgotypes.ReplyAccounts{}
reply.Accounts = accounts
return &reply, nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
func (e *evmxgo) ExecTransWithdraw(accountDB *account.DB, tx *types.Transaction, action *evmxgotypes.EvmxgoAction, index int) (*types.Receipt, error) {
switch {
case action.Ty == evmxgotypes.ActionTransfer && action.GetTransfer() != nil:
transfer := action.GetTransfer()
from := tx.From()
//to 是 execs 合约地址
if drivers.IsDriverAddress(transfer.To, e.GetHeight()) {
return accountDB.TransferToExec(from, transfer.To, transfer.Amount)
}
return accountDB.Transfer(from, transfer.To, transfer.Amount)
case action.Ty == evmxgotypes.ActionWithdraw && action.GetWithdraw() != nil:
withdraw := action.GetWithdraw()
from := tx.From()
//to 是 execs 合约地址
if drivers.IsDriverAddress(withdraw.To, e.GetHeight()) || isExecAddrMatch(withdraw.ExecName, withdraw.To) {
return accountDB.TransferWithdraw(from, withdraw.To, withdraw.Amount)
}
return nil, types.ErrActionNotSupport
case action.Ty == evmxgotypes.EvmxgoActionTransferToExec && action.GetTransferToExec() != nil:
transfer := action.GetTransferToExec()
from := tx.From()
//to 是 execs 合约地址
if !isExecAddrMatch(transfer.ExecName, transfer.To) {
return nil, types.ErrToAddrNotSameToExecAddr
}
return accountDB.TransferToExec(from, transfer.To, transfer.Amount)
default:
return nil, types.ErrActionNotSupport
}
}
func isExecAddrMatch(name string, to string) bool {
toaddr := address.ExecAddress(name)
return toaddr == to
}
//0: all tx
//1: from tx
//2: to tx
func (e *evmxgo) ExecLocalTransWithdraw(tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{}
if receipt.GetTy() != types.ExecOk {
return set, nil
}
//执行成功
var action evmxgotypes.EvmxgoAction
err := types.Decode(tx.GetPayload(), &action)
if err != nil {
panic(err)
}
var kv *types.KeyValue
if action.Ty == evmxgotypes.ActionTransfer && action.GetTransfer() != nil {
transfer := action.GetTransfer()
kv, err = updateAddrReciver(e.GetLocalDB(), transfer.Cointoken, transfer.To, transfer.Amount, true)
} else if action.Ty == evmxgotypes.ActionWithdraw && action.GetWithdraw() != nil {
withdraw := action.GetWithdraw()
from := tx.From()
kv, err = updateAddrReciver(e.GetLocalDB(), withdraw.Cointoken, from, withdraw.Amount, true)
} else if action.Ty == evmxgotypes.EvmxgoActionTransferToExec && action.GetTransferToExec() != nil {
transfer := action.GetTransferToExec()
kv, err = updateAddrReciver(e.GetLocalDB(), transfer.Cointoken, transfer.To, transfer.Amount, true)
}
if err != nil {
return set, nil
}
if kv != nil {
set.KV = append(set.KV, kv)
}
return set, nil
}
func (e *evmxgo) ExecDelLocalLocalTransWithdraw(tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{}
if receipt.GetTy() != types.ExecOk {
return set, nil
}
//执行成功
var action evmxgotypes.EvmxgoAction
err := types.Decode(tx.GetPayload(), &action)
if err != nil {
panic(err)
}
var kv *types.KeyValue
if action.Ty == evmxgotypes.ActionTransfer && action.GetTransfer() != nil {
transfer := action.GetTransfer()
kv, err = updateAddrReciver(e.GetLocalDB(), transfer.Cointoken, transfer.To, transfer.Amount, false)
} else if action.Ty == evmxgotypes.ActionWithdraw && action.GetWithdraw() != nil {
withdraw := action.GetWithdraw()
from := tx.From()
kv, err = updateAddrReciver(e.GetLocalDB(), withdraw.Cointoken, from, withdraw.Amount, false)
} else if action.Ty == evmxgotypes.EvmxgoActionTransferToExec && action.GetTransferToExec() != nil {
transfer := action.GetTransferToExec()
kv, err = updateAddrReciver(e.GetLocalDB(), transfer.Cointoken, transfer.To, transfer.Amount, false)
}
if err != nil {
return set, nil
}
if kv != nil {
set.KV = append(set.KV, kv)
}
return set, nil
}
func getAddrReciverKV(token string, addr string, reciverAmount int64) *types.KeyValue {
reciver := &types.Int64{Data: reciverAmount}
amountbytes := types.Encode(reciver)
kv := &types.KeyValue{Key: calcAddrKey(token, addr), Value: amountbytes}
return kv
}
func getAddrReciver(db dbm.KVDB, token string, addr string) (int64, error) {
reciver := types.Int64{}
addrReciver, err := db.Get(calcAddrKey(token, addr))
if err != nil && err != types.ErrNotFound {
return 0, err
}
if len(addrReciver) == 0 {
return 0, nil
}
err = types.Decode(addrReciver, &reciver)
if err != nil {
return 0, err
}
return reciver.Data, nil
}
func setAddrReciver(db dbm.KVDB, token string, addr string, reciverAmount int64) error {
kv := getAddrReciverKV(addr, token, reciverAmount)
return db.Set(kv.Key, kv.Value)
}
func updateAddrReciver(cachedb dbm.KVDB, token string, addr string, amount int64, isadd bool) (*types.KeyValue, error) {
recv, err := getAddrReciver(cachedb, token, addr)
if err != nil && err != types.ErrNotFound {
return nil, err
}
if isadd {
recv += amount
} else {
recv -= amount
}
err = setAddrReciver(cachedb, token, addr, recv)
if err != nil {
return nil, err
}
//keyvalue
return getAddrReciverKV(token, addr, recv), nil
}
package types
import (
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/evmxgo/commands"
"github.com/33cn/plugin/plugin/dapp/evmxgo/executor"
"github.com/33cn/plugin/plugin/dapp/evmxgo/rpc"
evmxgotypes "github.com/33cn/plugin/plugin/dapp/evmxgo/types"
)
/*
* 初始化dapp相关的组件
*/
func init() {
pluginmgr.Register(&pluginmgr.PluginBase{
Name: evmxgotypes.EvmxgoX,
ExecName: executor.GetName(),
Exec: executor.Init,
Cmd: commands.Cmd,
RPC: rpc.Init,
})
}
all:
bash ./create_protobuf.sh
#!/bin/bash
# proto生成命令,将pb.go文件生成到types/目录下, chain33_path支持引用chain33框架的proto文件
chain33_path=$(go list -f '{{.Dir}}' "github.com/33cn/chain33")
protoc --go_out=plugins=grpc:../types ./*.proto --proto_path=. --proto_path="${chain33_path}/types/proto/"
syntax = "proto3";
import "transaction.proto";
import "account.proto";
package types;
option go_package = "../types";
// action
message EvmxgoAction {
oneof value {
AssetsTransfer transfer = 1;
AssetsWithdraw withdraw = 2;
AssetsTransferToExec transferToExec = 3;
EvmxgoMint mint = 4;
EvmxgoBurn burn = 5;
}
int32 Ty = 6;
}
message EvmxgoMint {
string symbol = 1;
int64 amount = 2;
string bridgeToken = 3;
string recipient = 4;
}
message EvmxgoBurn {
string symbol = 1;
int64 amount = 2;
}
// state db
message Evmxgo {
string symbol = 1;
string introduction = 2;
int64 total = 3;
}
// config mint synbol
message EvmxgoMintConfig {
string address = 1;
int32 precision = 2;
string introduction = 3;
}
// config bridgevmxgo contract address
message BridgevmxgoConfig {
string address = 1;
}
// log
message ReceiptEvmxgo {
string symbol = 1;
}
message ReceiptEvmxgoAmount {
Evmxgo prev = 1;
Evmxgo current = 2;
}
// local
message LocalEvmxgo {
string symbol = 1;
string introduction = 2;
int64 total = 3;
int32 precision = 4;
}
message LocalEvmxgoLogs {
string symbol = 1;
string txIndex = 2;
int32 actionType = 3;
string txHash = 4;
}
// query
message ReqEvmxgos {
bool queryAll = 1;
repeated string tokens = 2;
}
message ReplyEvmxgos {
repeated LocalEvmxgo tokens = 1;
}
message EvmxgoRecv {
string evmxgo = 1;
int64 recv = 2;
}
message ReplyAddrRecvForEvmxgos {
repeated EvmxgoRecv evmxgoRecvs = 1;
}
message ReplyAccounts {
repeated Account accounts =1;
}
message ReqAccountEvmxgoAssets {
string address = 1;
string execer = 2;
}
message EvmxgoAsset {
string symbol = 1;
Account account = 2;
}
message ReplyAccountEvmxgoAssets {
repeated EvmxgoAsset evmxgoAssets = 1;
}
message ReqAddrEvmxgos {
string addr = 1;
int32 status = 2;
repeated string evmxgo = 3;
int32 direction = 4;
int32 count = 5;
string fromKey = 6;
}
message ReqEvmxgoTx {
string symbol = 1;
//表示取所有/from/to/其他的hash列表
int32 flag = 2;
int32 count = 3;
int32 direction = 4;
int64 height = 5;
int64 index = 6;
string addr = 7;
}
message ReplyEvmxgoLogs {
repeated LocalEvmxgoLogs logs = 1;
}
service evmxgo {}
package rpc
/*
* 实现json rpc和grpc service接口
* json rpc用Jrpc结构作为接收实例
* grpc使用channelClient结构作为接收实例
*/
package rpc
import (
rpctypes "github.com/33cn/chain33/rpc/types"
)
/*
* rpc相关结构定义和初始化
*/
// 实现grpc的service接口
type channelClient struct {
rpctypes.ChannelClient
}
// Jrpc 实现json rpc调用实例
type Jrpc struct {
cli *channelClient
}
// Grpc grpc
type Grpc struct {
*channelClient
}
// Init init rpc
func Init(name string, s rpctypes.RPCServer) {
cli := &channelClient{}
grpc := &Grpc{channelClient: cli}
cli.Init(name, s, &Jrpc{cli: cli}, grpc)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package types
const (
// ActionTransfer for transfer
ActionTransfer = 4
// ActionGenesis for genesis
ActionGenesis = 5
// ActionWithdraw for Withdraw
ActionWithdraw = 6
// EvmxgoActionTransferToExec for evmxgo transfer to exec
EvmxgoActionTransferToExec = 11
// EvmxgoActionMint for evmxgo mint
EvmxgoActionMint = 12
// EvmxgoActionBurn for evmxgo burn
EvmxgoActionBurn = 13
)
const (
// TyLogEvmxgoTransfer log for token tranfer
TyLogEvmxgoTransfer = 313
// TyLogEvmxgoDeposit log for token deposit
TyLogEvmxgoDeposit = 315
// TyLogEvmxgoExecTransfer log for token exec transfer
TyLogEvmxgoExecTransfer = 316
// TyLogEvmxgoExecWithdraw log for token exec withdraw
TyLogEvmxgoExecWithdraw = 317
// TyLogEvmxgoExecDeposit log for token exec deposit
TyLogEvmxgoExecDeposit = 318
// TyLogEvmxgoExecFrozen log for token exec frozen
TyLogEvmxgoExecFrozen = 319
// TyLogEvmxgoExecActive log for token exec active
TyLogEvmxgoExecActive = 320
// TyLogEvmxgoGenesisTransfer log for token genesis rransfer
TyLogEvmxgoGenesisTransfer = 321
// TyLogEvmxgoGenesisDeposit log for token genesis deposit
TyLogEvmxgoGenesisDeposit = 322
// TyLogEvmxgoMint log for evmxgo mint
TyLogEvmxgoMint = 323
// TyLogEvmxgoBurn log for evmxgo burn
TyLogEvmxgoBurn = 324
)
package types
import "errors"
var (
// ErrEvmxgoSymbolNotExist error evmxgo symbol not exist
ErrEvmxgoSymbolNotExist = errors.New("ErrEvmxgoSymbolNotExist")
// ErrEvmxgoSymbolNotAllowedMint error evmxgo symbol not allowed mint
ErrEvmxgoSymbolNotAllowedMint = errors.New("ErrEvmxgoSymbolNotAllowedMint")
// ErrEvmxgoSymbolNotConfigValue error evmxgo symbol not config value
ErrEvmxgoSymbolNotConfigValue = errors.New("ErrEvmxgoSymbolNotConfigValue")
// ErrNotCorrectBridgeTokenAddress error Not Correct BridgeToken Address
ErrNotCorrectBridgeTokenAddress = errors.New("ErrNotCorrectBridgeTokenAddress")
)
package types
import (
"reflect"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
)
/*
* 交易相关类型定义
* 交易action通常有对应的log结构,用于交易回执日志记录
* 每一种action和log需要用id数值和name名称加以区分
*/
// action类型id和name,这些常量可以自定义修改
const (
TyUnknowAction = iota + 100
TyTransferAction
TyWithdrawAction
TyTransferToExecAction
TyMintAction
TyBurnAction
NameTransferAction = "Transfer"
NameWithdrawAction = "Withdraw"
NameTransferToExecAction = "TransferToExec"
NameMintAction = "Mint"
NameBurnAction = "Burn"
)
// log类型id值
const (
TyUnknownLog = iota + 100
TyTransferLog
TyWithdrawLog
TyTransferToExecLog
TyMintLog
TyBurnLog
)
var (
//EvmxgoX 执行器名称定义
EvmxgoX = "evmxgo"
//定义actionMap
actionMap = map[string]int32{
NameTransferAction: TyTransferAction,
NameWithdrawAction: TyWithdrawAction,
NameTransferToExecAction: TyTransferToExecAction,
NameMintAction: TyMintAction,
NameBurnAction: TyBurnAction,
}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap = map[int64]*types.LogInfo{
//LogID: {Ty: reflect.TypeOf(LogStruct), Name: LogName},
}
tlog = log.New("module", "evmxgo.types")
)
// init defines a register function
func init() {
types.AllowUserExec = append(types.AllowUserExec, []byte(EvmxgoX))
//注册合约启用高度
types.RegFork(EvmxgoX, InitFork)
types.RegExec(EvmxgoX, InitExecutor)
}
// InitFork defines register fork
func InitFork(cfg *types.Chain33Config) {
cfg.RegisterDappFork(EvmxgoX, "Enable", 0)
}
// InitExecutor defines register executor
func InitExecutor(cfg *types.Chain33Config) {
types.RegistorExecutor(EvmxgoX, NewType(cfg))
}
type evmxgoType struct {
types.ExecTypeBase
}
func NewType(cfg *types.Chain33Config) *evmxgoType {
c := &evmxgoType{}
c.SetChild(c)
c.SetConfig(cfg)
return c
}
// GetPayload 获取合约action结构
func (e *evmxgoType) GetPayload() types.Message {
return &EvmxgoAction{}
}
// GetTypeMap 获取合约action的id和name信息
func (e *evmxgoType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Transfer": ActionTransfer,
"Withdraw": ActionWithdraw,
"TransferToExec": EvmxgoActionTransferToExec,
"Mint": EvmxgoActionMint,
"Burn": EvmxgoActionBurn,
}
}
// GetLogMap 获取合约log相关信息
func (e *evmxgoType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogEvmxgoTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogTokenTransfer"},
TyLogEvmxgoDeposit: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogTokenDeposit"},
TyLogEvmxgoExecTransfer: {Ty: reflect.TypeOf(types.ReceiptExecAccountTransfer{}), Name: "LogTokenExecTransfer"},
TyLogEvmxgoExecWithdraw: {Ty: reflect.TypeOf(types.ReceiptExecAccountTransfer{}), Name: "LogTokenExecWithdraw"},
TyLogEvmxgoExecDeposit: {Ty: reflect.TypeOf(types.ReceiptExecAccountTransfer{}), Name: "LogTokenExecDeposit"},
TyLogEvmxgoExecFrozen: {Ty: reflect.TypeOf(types.ReceiptExecAccountTransfer{}), Name: "LogTokenExecFrozen"},
TyLogEvmxgoExecActive: {Ty: reflect.TypeOf(types.ReceiptExecAccountTransfer{}), Name: "LogTokenExecActive"},
TyLogEvmxgoGenesisTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogTokenGenesisTransfer"},
TyLogEvmxgoGenesisDeposit: {Ty: reflect.TypeOf(types.ReceiptExecAccountTransfer{}), Name: "LogTokenGenesisDeposit"},
TyLogEvmxgoMint: {Ty: reflect.TypeOf(ReceiptEvmxgoAmount{}), Name: "LogMintToken"},
TyLogEvmxgoBurn: {Ty: reflect.TypeOf(ReceiptEvmxgoAmount{}), Name: "LogBurnToken"},
}
}
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.9.1
// source: evmxgo.proto
package types
import (
context "context"
reflect "reflect"
sync "sync"
types "github.com/33cn/chain33/types"
grpc "google.golang.org/grpc"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// action
type EvmxgoAction struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Types that are assignable to Value:
// *EvmxgoAction_Transfer
// *EvmxgoAction_Withdraw
// *EvmxgoAction_TransferToExec
// *EvmxgoAction_Mint
// *EvmxgoAction_Burn
Value isEvmxgoAction_Value `protobuf_oneof:"value"`
Ty int32 `protobuf:"varint,6,opt,name=Ty,proto3" json:"Ty,omitempty"`
}
func (x *EvmxgoAction) Reset() {
*x = EvmxgoAction{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EvmxgoAction) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EvmxgoAction) ProtoMessage() {}
func (x *EvmxgoAction) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EvmxgoAction.ProtoReflect.Descriptor instead.
func (*EvmxgoAction) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{0}
}
func (m *EvmxgoAction) GetValue() isEvmxgoAction_Value {
if m != nil {
return m.Value
}
return nil
}
func (x *EvmxgoAction) GetTransfer() *types.AssetsTransfer {
if x, ok := x.GetValue().(*EvmxgoAction_Transfer); ok {
return x.Transfer
}
return nil
}
func (x *EvmxgoAction) GetWithdraw() *types.AssetsWithdraw {
if x, ok := x.GetValue().(*EvmxgoAction_Withdraw); ok {
return x.Withdraw
}
return nil
}
func (x *EvmxgoAction) GetTransferToExec() *types.AssetsTransferToExec {
if x, ok := x.GetValue().(*EvmxgoAction_TransferToExec); ok {
return x.TransferToExec
}
return nil
}
func (x *EvmxgoAction) GetMint() *EvmxgoMint {
if x, ok := x.GetValue().(*EvmxgoAction_Mint); ok {
return x.Mint
}
return nil
}
func (x *EvmxgoAction) GetBurn() *EvmxgoBurn {
if x, ok := x.GetValue().(*EvmxgoAction_Burn); ok {
return x.Burn
}
return nil
}
func (x *EvmxgoAction) GetTy() int32 {
if x != nil {
return x.Ty
}
return 0
}
type isEvmxgoAction_Value interface {
isEvmxgoAction_Value()
}
type EvmxgoAction_Transfer struct {
Transfer *types.AssetsTransfer `protobuf:"bytes,1,opt,name=transfer,proto3,oneof"`
}
type EvmxgoAction_Withdraw struct {
Withdraw *types.AssetsWithdraw `protobuf:"bytes,2,opt,name=withdraw,proto3,oneof"`
}
type EvmxgoAction_TransferToExec struct {
TransferToExec *types.AssetsTransferToExec `protobuf:"bytes,3,opt,name=transferToExec,proto3,oneof"`
}
type EvmxgoAction_Mint struct {
Mint *EvmxgoMint `protobuf:"bytes,4,opt,name=mint,proto3,oneof"`
}
type EvmxgoAction_Burn struct {
Burn *EvmxgoBurn `protobuf:"bytes,5,opt,name=burn,proto3,oneof"`
}
func (*EvmxgoAction_Transfer) isEvmxgoAction_Value() {}
func (*EvmxgoAction_Withdraw) isEvmxgoAction_Value() {}
func (*EvmxgoAction_TransferToExec) isEvmxgoAction_Value() {}
func (*EvmxgoAction_Mint) isEvmxgoAction_Value() {}
func (*EvmxgoAction_Burn) isEvmxgoAction_Value() {}
type EvmxgoMint struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"`
Amount int64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"`
BridgeToken string `protobuf:"bytes,3,opt,name=bridgeToken,proto3" json:"bridgeToken,omitempty"`
Recipient string `protobuf:"bytes,4,opt,name=recipient,proto3" json:"recipient,omitempty"`
}
func (x *EvmxgoMint) Reset() {
*x = EvmxgoMint{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EvmxgoMint) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EvmxgoMint) ProtoMessage() {}
func (x *EvmxgoMint) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EvmxgoMint.ProtoReflect.Descriptor instead.
func (*EvmxgoMint) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{1}
}
func (x *EvmxgoMint) GetSymbol() string {
if x != nil {
return x.Symbol
}
return ""
}
func (x *EvmxgoMint) GetAmount() int64 {
if x != nil {
return x.Amount
}
return 0
}
func (x *EvmxgoMint) GetBridgeToken() string {
if x != nil {
return x.BridgeToken
}
return ""
}
func (x *EvmxgoMint) GetRecipient() string {
if x != nil {
return x.Recipient
}
return ""
}
type EvmxgoBurn struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"`
Amount int64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"`
}
func (x *EvmxgoBurn) Reset() {
*x = EvmxgoBurn{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EvmxgoBurn) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EvmxgoBurn) ProtoMessage() {}
func (x *EvmxgoBurn) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EvmxgoBurn.ProtoReflect.Descriptor instead.
func (*EvmxgoBurn) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{2}
}
func (x *EvmxgoBurn) GetSymbol() string {
if x != nil {
return x.Symbol
}
return ""
}
func (x *EvmxgoBurn) GetAmount() int64 {
if x != nil {
return x.Amount
}
return 0
}
// state db
type Evmxgo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"`
Introduction string `protobuf:"bytes,2,opt,name=introduction,proto3" json:"introduction,omitempty"`
Total int64 `protobuf:"varint,3,opt,name=total,proto3" json:"total,omitempty"`
}
func (x *Evmxgo) Reset() {
*x = Evmxgo{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Evmxgo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Evmxgo) ProtoMessage() {}
func (x *Evmxgo) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Evmxgo.ProtoReflect.Descriptor instead.
func (*Evmxgo) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{3}
}
func (x *Evmxgo) GetSymbol() string {
if x != nil {
return x.Symbol
}
return ""
}
func (x *Evmxgo) GetIntroduction() string {
if x != nil {
return x.Introduction
}
return ""
}
func (x *Evmxgo) GetTotal() int64 {
if x != nil {
return x.Total
}
return 0
}
// config mint synbol
type EvmxgoMintConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Precision int32 `protobuf:"varint,2,opt,name=precision,proto3" json:"precision,omitempty"`
Introduction string `protobuf:"bytes,3,opt,name=introduction,proto3" json:"introduction,omitempty"`
}
func (x *EvmxgoMintConfig) Reset() {
*x = EvmxgoMintConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EvmxgoMintConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EvmxgoMintConfig) ProtoMessage() {}
func (x *EvmxgoMintConfig) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EvmxgoMintConfig.ProtoReflect.Descriptor instead.
func (*EvmxgoMintConfig) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{4}
}
func (x *EvmxgoMintConfig) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *EvmxgoMintConfig) GetPrecision() int32 {
if x != nil {
return x.Precision
}
return 0
}
func (x *EvmxgoMintConfig) GetIntroduction() string {
if x != nil {
return x.Introduction
}
return ""
}
// config bridgevmxgo contract address
type BridgevmxgoConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
}
func (x *BridgevmxgoConfig) Reset() {
*x = BridgevmxgoConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BridgevmxgoConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BridgevmxgoConfig) ProtoMessage() {}
func (x *BridgevmxgoConfig) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BridgevmxgoConfig.ProtoReflect.Descriptor instead.
func (*BridgevmxgoConfig) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{5}
}
func (x *BridgevmxgoConfig) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
// log
type ReceiptEvmxgo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"`
}
func (x *ReceiptEvmxgo) Reset() {
*x = ReceiptEvmxgo{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReceiptEvmxgo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReceiptEvmxgo) ProtoMessage() {}
func (x *ReceiptEvmxgo) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReceiptEvmxgo.ProtoReflect.Descriptor instead.
func (*ReceiptEvmxgo) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{6}
}
func (x *ReceiptEvmxgo) GetSymbol() string {
if x != nil {
return x.Symbol
}
return ""
}
type ReceiptEvmxgoAmount struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Prev *Evmxgo `protobuf:"bytes,1,opt,name=prev,proto3" json:"prev,omitempty"`
Current *Evmxgo `protobuf:"bytes,2,opt,name=current,proto3" json:"current,omitempty"`
}
func (x *ReceiptEvmxgoAmount) Reset() {
*x = ReceiptEvmxgoAmount{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReceiptEvmxgoAmount) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReceiptEvmxgoAmount) ProtoMessage() {}
func (x *ReceiptEvmxgoAmount) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReceiptEvmxgoAmount.ProtoReflect.Descriptor instead.
func (*ReceiptEvmxgoAmount) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{7}
}
func (x *ReceiptEvmxgoAmount) GetPrev() *Evmxgo {
if x != nil {
return x.Prev
}
return nil
}
func (x *ReceiptEvmxgoAmount) GetCurrent() *Evmxgo {
if x != nil {
return x.Current
}
return nil
}
// local
type LocalEvmxgo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"`
Introduction string `protobuf:"bytes,2,opt,name=introduction,proto3" json:"introduction,omitempty"`
Total int64 `protobuf:"varint,3,opt,name=total,proto3" json:"total,omitempty"`
Precision int32 `protobuf:"varint,4,opt,name=precision,proto3" json:"precision,omitempty"`
}
func (x *LocalEvmxgo) Reset() {
*x = LocalEvmxgo{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LocalEvmxgo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LocalEvmxgo) ProtoMessage() {}
func (x *LocalEvmxgo) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LocalEvmxgo.ProtoReflect.Descriptor instead.
func (*LocalEvmxgo) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{8}
}
func (x *LocalEvmxgo) GetSymbol() string {
if x != nil {
return x.Symbol
}
return ""
}
func (x *LocalEvmxgo) GetIntroduction() string {
if x != nil {
return x.Introduction
}
return ""
}
func (x *LocalEvmxgo) GetTotal() int64 {
if x != nil {
return x.Total
}
return 0
}
func (x *LocalEvmxgo) GetPrecision() int32 {
if x != nil {
return x.Precision
}
return 0
}
type LocalEvmxgoLogs struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"`
TxIndex string `protobuf:"bytes,2,opt,name=txIndex,proto3" json:"txIndex,omitempty"`
ActionType int32 `protobuf:"varint,3,opt,name=actionType,proto3" json:"actionType,omitempty"`
TxHash string `protobuf:"bytes,4,opt,name=txHash,proto3" json:"txHash,omitempty"`
}
func (x *LocalEvmxgoLogs) Reset() {
*x = LocalEvmxgoLogs{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LocalEvmxgoLogs) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LocalEvmxgoLogs) ProtoMessage() {}
func (x *LocalEvmxgoLogs) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LocalEvmxgoLogs.ProtoReflect.Descriptor instead.
func (*LocalEvmxgoLogs) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{9}
}
func (x *LocalEvmxgoLogs) GetSymbol() string {
if x != nil {
return x.Symbol
}
return ""
}
func (x *LocalEvmxgoLogs) GetTxIndex() string {
if x != nil {
return x.TxIndex
}
return ""
}
func (x *LocalEvmxgoLogs) GetActionType() int32 {
if x != nil {
return x.ActionType
}
return 0
}
func (x *LocalEvmxgoLogs) GetTxHash() string {
if x != nil {
return x.TxHash
}
return ""
}
// query
type ReqEvmxgos struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
QueryAll bool `protobuf:"varint,1,opt,name=queryAll,proto3" json:"queryAll,omitempty"`
Tokens []string `protobuf:"bytes,2,rep,name=tokens,proto3" json:"tokens,omitempty"`
}
func (x *ReqEvmxgos) Reset() {
*x = ReqEvmxgos{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReqEvmxgos) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReqEvmxgos) ProtoMessage() {}
func (x *ReqEvmxgos) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReqEvmxgos.ProtoReflect.Descriptor instead.
func (*ReqEvmxgos) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{10}
}
func (x *ReqEvmxgos) GetQueryAll() bool {
if x != nil {
return x.QueryAll
}
return false
}
func (x *ReqEvmxgos) GetTokens() []string {
if x != nil {
return x.Tokens
}
return nil
}
type ReplyEvmxgos struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Tokens []*LocalEvmxgo `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"`
}
func (x *ReplyEvmxgos) Reset() {
*x = ReplyEvmxgos{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReplyEvmxgos) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReplyEvmxgos) ProtoMessage() {}
func (x *ReplyEvmxgos) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReplyEvmxgos.ProtoReflect.Descriptor instead.
func (*ReplyEvmxgos) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{11}
}
func (x *ReplyEvmxgos) GetTokens() []*LocalEvmxgo {
if x != nil {
return x.Tokens
}
return nil
}
type EvmxgoRecv struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Evmxgo string `protobuf:"bytes,1,opt,name=evmxgo,proto3" json:"evmxgo,omitempty"`
Recv int64 `protobuf:"varint,2,opt,name=recv,proto3" json:"recv,omitempty"`
}
func (x *EvmxgoRecv) Reset() {
*x = EvmxgoRecv{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EvmxgoRecv) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EvmxgoRecv) ProtoMessage() {}
func (x *EvmxgoRecv) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EvmxgoRecv.ProtoReflect.Descriptor instead.
func (*EvmxgoRecv) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{12}
}
func (x *EvmxgoRecv) GetEvmxgo() string {
if x != nil {
return x.Evmxgo
}
return ""
}
func (x *EvmxgoRecv) GetRecv() int64 {
if x != nil {
return x.Recv
}
return 0
}
type ReplyAddrRecvForEvmxgos struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
EvmxgoRecvs []*EvmxgoRecv `protobuf:"bytes,1,rep,name=evmxgoRecvs,proto3" json:"evmxgoRecvs,omitempty"`
}
func (x *ReplyAddrRecvForEvmxgos) Reset() {
*x = ReplyAddrRecvForEvmxgos{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReplyAddrRecvForEvmxgos) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReplyAddrRecvForEvmxgos) ProtoMessage() {}
func (x *ReplyAddrRecvForEvmxgos) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[13]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReplyAddrRecvForEvmxgos.ProtoReflect.Descriptor instead.
func (*ReplyAddrRecvForEvmxgos) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{13}
}
func (x *ReplyAddrRecvForEvmxgos) GetEvmxgoRecvs() []*EvmxgoRecv {
if x != nil {
return x.EvmxgoRecvs
}
return nil
}
type ReplyAccounts struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Accounts []*types.Account `protobuf:"bytes,1,rep,name=accounts,proto3" json:"accounts,omitempty"`
}
func (x *ReplyAccounts) Reset() {
*x = ReplyAccounts{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReplyAccounts) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReplyAccounts) ProtoMessage() {}
func (x *ReplyAccounts) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[14]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReplyAccounts.ProtoReflect.Descriptor instead.
func (*ReplyAccounts) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{14}
}
func (x *ReplyAccounts) GetAccounts() []*types.Account {
if x != nil {
return x.Accounts
}
return nil
}
type ReqAccountEvmxgoAssets struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Execer string `protobuf:"bytes,2,opt,name=execer,proto3" json:"execer,omitempty"`
}
func (x *ReqAccountEvmxgoAssets) Reset() {
*x = ReqAccountEvmxgoAssets{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReqAccountEvmxgoAssets) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReqAccountEvmxgoAssets) ProtoMessage() {}
func (x *ReqAccountEvmxgoAssets) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[15]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReqAccountEvmxgoAssets.ProtoReflect.Descriptor instead.
func (*ReqAccountEvmxgoAssets) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{15}
}
func (x *ReqAccountEvmxgoAssets) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *ReqAccountEvmxgoAssets) GetExecer() string {
if x != nil {
return x.Execer
}
return ""
}
type EvmxgoAsset struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"`
Account *types.Account `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"`
}
func (x *EvmxgoAsset) Reset() {
*x = EvmxgoAsset{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EvmxgoAsset) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EvmxgoAsset) ProtoMessage() {}
func (x *EvmxgoAsset) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EvmxgoAsset.ProtoReflect.Descriptor instead.
func (*EvmxgoAsset) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{16}
}
func (x *EvmxgoAsset) GetSymbol() string {
if x != nil {
return x.Symbol
}
return ""
}
func (x *EvmxgoAsset) GetAccount() *types.Account {
if x != nil {
return x.Account
}
return nil
}
type ReplyAccountEvmxgoAssets struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
EvmxgoAssets []*EvmxgoAsset `protobuf:"bytes,1,rep,name=evmxgoAssets,proto3" json:"evmxgoAssets,omitempty"`
}
func (x *ReplyAccountEvmxgoAssets) Reset() {
*x = ReplyAccountEvmxgoAssets{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReplyAccountEvmxgoAssets) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReplyAccountEvmxgoAssets) ProtoMessage() {}
func (x *ReplyAccountEvmxgoAssets) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReplyAccountEvmxgoAssets.ProtoReflect.Descriptor instead.
func (*ReplyAccountEvmxgoAssets) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{17}
}
func (x *ReplyAccountEvmxgoAssets) GetEvmxgoAssets() []*EvmxgoAsset {
if x != nil {
return x.EvmxgoAssets
}
return nil
}
type ReqAddrEvmxgos struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
Evmxgo []string `protobuf:"bytes,3,rep,name=evmxgo,proto3" json:"evmxgo,omitempty"`
Direction int32 `protobuf:"varint,4,opt,name=direction,proto3" json:"direction,omitempty"`
Count int32 `protobuf:"varint,5,opt,name=count,proto3" json:"count,omitempty"`
FromKey string `protobuf:"bytes,6,opt,name=fromKey,proto3" json:"fromKey,omitempty"`
}
func (x *ReqAddrEvmxgos) Reset() {
*x = ReqAddrEvmxgos{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReqAddrEvmxgos) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReqAddrEvmxgos) ProtoMessage() {}
func (x *ReqAddrEvmxgos) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReqAddrEvmxgos.ProtoReflect.Descriptor instead.
func (*ReqAddrEvmxgos) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{18}
}
func (x *ReqAddrEvmxgos) GetAddr() string {
if x != nil {
return x.Addr
}
return ""
}
func (x *ReqAddrEvmxgos) GetStatus() int32 {
if x != nil {
return x.Status
}
return 0
}
func (x *ReqAddrEvmxgos) GetEvmxgo() []string {
if x != nil {
return x.Evmxgo
}
return nil
}
func (x *ReqAddrEvmxgos) GetDirection() int32 {
if x != nil {
return x.Direction
}
return 0
}
func (x *ReqAddrEvmxgos) GetCount() int32 {
if x != nil {
return x.Count
}
return 0
}
func (x *ReqAddrEvmxgos) GetFromKey() string {
if x != nil {
return x.FromKey
}
return ""
}
type ReqEvmxgoTx struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"`
//表示取所有/from/to/其他的hash列表
Flag int32 `protobuf:"varint,2,opt,name=flag,proto3" json:"flag,omitempty"`
Count int32 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"`
Direction int32 `protobuf:"varint,4,opt,name=direction,proto3" json:"direction,omitempty"`
Height int64 `protobuf:"varint,5,opt,name=height,proto3" json:"height,omitempty"`
Index int64 `protobuf:"varint,6,opt,name=index,proto3" json:"index,omitempty"`
Addr string `protobuf:"bytes,7,opt,name=addr,proto3" json:"addr,omitempty"`
}
func (x *ReqEvmxgoTx) Reset() {
*x = ReqEvmxgoTx{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReqEvmxgoTx) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReqEvmxgoTx) ProtoMessage() {}
func (x *ReqEvmxgoTx) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReqEvmxgoTx.ProtoReflect.Descriptor instead.
func (*ReqEvmxgoTx) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{19}
}
func (x *ReqEvmxgoTx) GetSymbol() string {
if x != nil {
return x.Symbol
}
return ""
}
func (x *ReqEvmxgoTx) GetFlag() int32 {
if x != nil {
return x.Flag
}
return 0
}
func (x *ReqEvmxgoTx) GetCount() int32 {
if x != nil {
return x.Count
}
return 0
}
func (x *ReqEvmxgoTx) GetDirection() int32 {
if x != nil {
return x.Direction
}
return 0
}
func (x *ReqEvmxgoTx) GetHeight() int64 {
if x != nil {
return x.Height
}
return 0
}
func (x *ReqEvmxgoTx) GetIndex() int64 {
if x != nil {
return x.Index
}
return 0
}
func (x *ReqEvmxgoTx) GetAddr() string {
if x != nil {
return x.Addr
}
return ""
}
type ReplyEvmxgoLogs struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Logs []*LocalEvmxgoLogs `protobuf:"bytes,1,rep,name=logs,proto3" json:"logs,omitempty"`
}
func (x *ReplyEvmxgoLogs) Reset() {
*x = ReplyEvmxgoLogs{}
if protoimpl.UnsafeEnabled {
mi := &file_evmxgo_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ReplyEvmxgoLogs) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReplyEvmxgoLogs) ProtoMessage() {}
func (x *ReplyEvmxgoLogs) ProtoReflect() protoreflect.Message {
mi := &file_evmxgo_proto_msgTypes[20]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ReplyEvmxgoLogs.ProtoReflect.Descriptor instead.
func (*ReplyEvmxgoLogs) Descriptor() ([]byte, []int) {
return file_evmxgo_proto_rawDescGZIP(), []int{20}
}
func (x *ReplyEvmxgoLogs) GetLogs() []*LocalEvmxgoLogs {
if x != nil {
return x.Logs
}
return nil
}
var File_evmxgo_proto protoreflect.FileDescriptor
var file_evmxgo_proto_rawDesc = []byte{
0x0a, 0x0c, 0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05,
0x74, 0x79, 0x70, 0x65, 0x73, 0x1a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaa, 0x02, 0x0a, 0x0c, 0x45, 0x76, 0x6d, 0x78,
0x67, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x66, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70,
0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
0x72, 0x48, 0x00, 0x52, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x33, 0x0a,
0x08, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x57, 0x69,
0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x48, 0x00, 0x52, 0x08, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72,
0x61, 0x77, 0x12, 0x45, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x6f,
0x45, 0x78, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x79, 0x70,
0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
0x72, 0x54, 0x6f, 0x45, 0x78, 0x65, 0x63, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73,
0x66, 0x65, 0x72, 0x54, 0x6f, 0x45, 0x78, 0x65, 0x63, 0x12, 0x27, 0x0a, 0x04, 0x6d, 0x69, 0x6e,
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x4d, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x69,
0x6e, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x62, 0x75, 0x72, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x42,
0x75, 0x72, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x62, 0x75, 0x72, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x54,
0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x54, 0x79, 0x42, 0x07, 0x0a, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x22, 0x7c, 0x0a, 0x0a, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x4d, 0x69,
0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d,
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75,
0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e,
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65,
0x6e, 0x74, 0x22, 0x3c, 0x0a, 0x0a, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x42, 0x75, 0x72, 0x6e,
0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75,
0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
0x22, 0x5a, 0x0a, 0x06, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79,
0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62,
0x6f, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64,
0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18,
0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x6e, 0x0a, 0x10,
0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x4d, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72,
0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x70,
0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x72,
0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2d, 0x0a, 0x11,
0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x27, 0x0a, 0x0d, 0x52,
0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x12, 0x16, 0x0a, 0x06,
0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79,
0x6d, 0x62, 0x6f, 0x6c, 0x22, 0x61, 0x0a, 0x13, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x45,
0x76, 0x6d, 0x78, 0x67, 0x6f, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x04, 0x70,
0x72, 0x65, 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65,
0x73, 0x2e, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x52, 0x04, 0x70, 0x72, 0x65, 0x76, 0x12, 0x27,
0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x52, 0x07,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x22, 0x7d, 0x0a, 0x0b, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x22,
0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28,
0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x63,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x70, 0x72, 0x65,
0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x7b, 0x0a, 0x0f, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45,
0x76, 0x6d, 0x78, 0x67, 0x6f, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d,
0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f,
0x6c, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1e, 0x0a, 0x0a, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74,
0x78, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48,
0x61, 0x73, 0x68, 0x22, 0x40, 0x0a, 0x0a, 0x52, 0x65, 0x71, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f,
0x73, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x18, 0x01, 0x20,
0x01, 0x28, 0x08, 0x52, 0x08, 0x71, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x12, 0x16, 0x0a,
0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x3a, 0x0a, 0x0c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x45, 0x76,
0x6d, 0x78, 0x67, 0x6f, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4c, 0x6f,
0x63, 0x61, 0x6c, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x73, 0x22, 0x38, 0x0a, 0x0a, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x52, 0x65, 0x63, 0x76, 0x12,
0x16, 0x0a, 0x06, 0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x63, 0x76, 0x18,
0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x72, 0x65, 0x63, 0x76, 0x22, 0x4e, 0x0a, 0x17, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x41, 0x64, 0x64, 0x72, 0x52, 0x65, 0x63, 0x76, 0x46, 0x6f, 0x72, 0x45,
0x76, 0x6d, 0x78, 0x67, 0x6f, 0x73, 0x12, 0x33, 0x0a, 0x0b, 0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f,
0x52, 0x65, 0x63, 0x76, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79,
0x70, 0x65, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x52, 0x65, 0x63, 0x76, 0x52, 0x0b,
0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x52, 0x65, 0x63, 0x76, 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x08,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e,
0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x08,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x4a, 0x0a, 0x16, 0x52, 0x65, 0x71, 0x41,
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x41, 0x73, 0x73, 0x65,
0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06,
0x65, 0x78, 0x65, 0x63, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x78,
0x65, 0x63, 0x65, 0x72, 0x22, 0x4f, 0x0a, 0x0b, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x41, 0x73,
0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x28, 0x0a, 0x07, 0x61,
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74,
0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x52, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x41, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x41, 0x73, 0x73, 0x65, 0x74,
0x73, 0x12, 0x36, 0x0a, 0x0c, 0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x41, 0x73, 0x73, 0x65, 0x74,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x0c, 0x65, 0x76, 0x6d,
0x78, 0x67, 0x6f, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x0e, 0x52, 0x65,
0x71, 0x41, 0x64, 0x64, 0x72, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04,
0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72,
0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x76, 0x6d, 0x78,
0x67, 0x6f, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f,
0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20,
0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14,
0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x72, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x18,
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x72, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x22, 0xaf,
0x01, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x54, 0x78, 0x12, 0x16,
0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x6c, 0x61, 0x67, 0x18, 0x02,
0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x66, 0x6c, 0x61, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20,
0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16,
0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04,
0x61, 0x64, 0x64, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72,
0x22, 0x3d, 0x0a, 0x0f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x45, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x4c,
0x6f, 0x67, 0x73, 0x12, 0x2a, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45,
0x76, 0x6d, 0x78, 0x67, 0x6f, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x32,
0x08, 0x0a, 0x06, 0x65, 0x76, 0x6d, 0x78, 0x67, 0x6f, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2e, 0x2f,
0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_evmxgo_proto_rawDescOnce sync.Once
file_evmxgo_proto_rawDescData = file_evmxgo_proto_rawDesc
)
func file_evmxgo_proto_rawDescGZIP() []byte {
file_evmxgo_proto_rawDescOnce.Do(func() {
file_evmxgo_proto_rawDescData = protoimpl.X.CompressGZIP(file_evmxgo_proto_rawDescData)
})
return file_evmxgo_proto_rawDescData
}
var file_evmxgo_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
var file_evmxgo_proto_goTypes = []interface{}{
(*EvmxgoAction)(nil), // 0: types.EvmxgoAction
(*EvmxgoMint)(nil), // 1: types.EvmxgoMint
(*EvmxgoBurn)(nil), // 2: types.EvmxgoBurn
(*Evmxgo)(nil), // 3: types.Evmxgo
(*EvmxgoMintConfig)(nil), // 4: types.EvmxgoMintConfig
(*BridgevmxgoConfig)(nil), // 5: types.BridgevmxgoConfig
(*ReceiptEvmxgo)(nil), // 6: types.ReceiptEvmxgo
(*ReceiptEvmxgoAmount)(nil), // 7: types.ReceiptEvmxgoAmount
(*LocalEvmxgo)(nil), // 8: types.LocalEvmxgo
(*LocalEvmxgoLogs)(nil), // 9: types.LocalEvmxgoLogs
(*ReqEvmxgos)(nil), // 10: types.ReqEvmxgos
(*ReplyEvmxgos)(nil), // 11: types.ReplyEvmxgos
(*EvmxgoRecv)(nil), // 12: types.EvmxgoRecv
(*ReplyAddrRecvForEvmxgos)(nil), // 13: types.ReplyAddrRecvForEvmxgos
(*ReplyAccounts)(nil), // 14: types.ReplyAccounts
(*ReqAccountEvmxgoAssets)(nil), // 15: types.ReqAccountEvmxgoAssets
(*EvmxgoAsset)(nil), // 16: types.EvmxgoAsset
(*ReplyAccountEvmxgoAssets)(nil), // 17: types.ReplyAccountEvmxgoAssets
(*ReqAddrEvmxgos)(nil), // 18: types.ReqAddrEvmxgos
(*ReqEvmxgoTx)(nil), // 19: types.ReqEvmxgoTx
(*ReplyEvmxgoLogs)(nil), // 20: types.ReplyEvmxgoLogs
(*types.AssetsTransfer)(nil), // 21: types.AssetsTransfer
(*types.AssetsWithdraw)(nil), // 22: types.AssetsWithdraw
(*types.AssetsTransferToExec)(nil), // 23: types.AssetsTransferToExec
(*types.Account)(nil), // 24: types.Account
}
var file_evmxgo_proto_depIdxs = []int32{
21, // 0: types.EvmxgoAction.transfer:type_name -> types.AssetsTransfer
22, // 1: types.EvmxgoAction.withdraw:type_name -> types.AssetsWithdraw
23, // 2: types.EvmxgoAction.transferToExec:type_name -> types.AssetsTransferToExec
1, // 3: types.EvmxgoAction.mint:type_name -> types.EvmxgoMint
2, // 4: types.EvmxgoAction.burn:type_name -> types.EvmxgoBurn
3, // 5: types.ReceiptEvmxgoAmount.prev:type_name -> types.Evmxgo
3, // 6: types.ReceiptEvmxgoAmount.current:type_name -> types.Evmxgo
8, // 7: types.ReplyEvmxgos.tokens:type_name -> types.LocalEvmxgo
12, // 8: types.ReplyAddrRecvForEvmxgos.evmxgoRecvs:type_name -> types.EvmxgoRecv
24, // 9: types.ReplyAccounts.accounts:type_name -> types.Account
24, // 10: types.EvmxgoAsset.account:type_name -> types.Account
16, // 11: types.ReplyAccountEvmxgoAssets.evmxgoAssets:type_name -> types.EvmxgoAsset
9, // 12: types.ReplyEvmxgoLogs.logs:type_name -> types.LocalEvmxgoLogs
13, // [13:13] is the sub-list for method output_type
13, // [13:13] is the sub-list for method input_type
13, // [13:13] is the sub-list for extension type_name
13, // [13:13] is the sub-list for extension extendee
0, // [0:13] is the sub-list for field type_name
}
func init() { file_evmxgo_proto_init() }
func file_evmxgo_proto_init() {
if File_evmxgo_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_evmxgo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EvmxgoAction); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EvmxgoMint); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EvmxgoBurn); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Evmxgo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EvmxgoMintConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BridgevmxgoConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReceiptEvmxgo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReceiptEvmxgoAmount); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LocalEvmxgo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LocalEvmxgoLogs); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqEvmxgos); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReplyEvmxgos); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EvmxgoRecv); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReplyAddrRecvForEvmxgos); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReplyAccounts); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqAccountEvmxgoAssets); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EvmxgoAsset); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReplyAccountEvmxgoAssets); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqAddrEvmxgos); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqEvmxgoTx); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_evmxgo_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReplyEvmxgoLogs); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_evmxgo_proto_msgTypes[0].OneofWrappers = []interface{}{
(*EvmxgoAction_Transfer)(nil),
(*EvmxgoAction_Withdraw)(nil),
(*EvmxgoAction_TransferToExec)(nil),
(*EvmxgoAction_Mint)(nil),
(*EvmxgoAction_Burn)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_evmxgo_proto_rawDesc,
NumEnums: 0,
NumMessages: 21,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_evmxgo_proto_goTypes,
DependencyIndexes: file_evmxgo_proto_depIdxs,
MessageInfos: file_evmxgo_proto_msgTypes,
}.Build()
File_evmxgo_proto = out.File
file_evmxgo_proto_rawDesc = nil
file_evmxgo_proto_goTypes = nil
file_evmxgo_proto_depIdxs = nil
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// EvmxgoClient is the client API for Evmxgo service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type EvmxgoClient interface {
}
type evmxgoClient struct {
cc grpc.ClientConnInterface
}
func NewEvmxgoClient(cc grpc.ClientConnInterface) EvmxgoClient {
return &evmxgoClient{cc}
}
// EvmxgoServer is the server API for Evmxgo service.
type EvmxgoServer interface {
}
// UnimplementedEvmxgoServer can be embedded to have forward compatible implementations.
type UnimplementedEvmxgoServer struct {
}
func RegisterEvmxgoServer(s *grpc.Server, srv EvmxgoServer) {
s.RegisterService(&_Evmxgo_serviceDesc, srv)
}
var _Evmxgo_serviceDesc = grpc.ServiceDesc{
ServiceName: "types.evmxgo",
HandlerType: (*EvmxgoServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{},
Metadata: "evmxgo.proto",
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package types
// EvmxgoAccountResult about evmxgo account result
type EvmxgoAccountResult struct {
Token string `json:"Token,omitempty"`
Currency int32 `json:"currency,omitempty"`
Balance string `json:"balance,omitempty"`
Frozen string `json:"frozen,omitempty"`
Addr string `json:"addr,omitempty"`
}
......@@ -10,6 +10,7 @@ import (
_ "github.com/33cn/plugin/plugin/dapp/dposvote" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/echo" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/evm" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/evmxgo" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/exchange" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/game" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/guess" //auto gen
......
......@@ -336,6 +336,9 @@ ForkEVMKVHash=0
ForkEVMYoloV1=0
ForkEVMTxGroup=0
[fork.sub.evmxgo]
Enable=0
[fork.sub.blackwhite]
Enable=0
ForkBlackWhiteV2=0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment