github.com/Onther-Tech/plasma-evm@v0.0.0-rc7.7/contracts/plasma/plasma.go (about)

     1  package plasma
     2  
     3  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/RootChain.sol --pkg rootchain --out rootchain/rootchain.go
     4  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/handlers/EpochHandler.sol --pkg epochhandler --out epochhandler/epochhandler.go
     5  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/handlers/SubmitHandler.sol --pkg submithandler --out submithandler/submithandler.go
     6  
     7  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/stake/tokens//TON.sol --pkg ton --out ton/ton.go
     8  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/stake/tokens/WTON.sol --pkg wton --out wton/wton.go
     9  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/stake/managers/DepositManager.sol --pkg depositmanager --out depositmanager/depositmanager.go
    10  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/stake/managers/SeigManager.sol --pkg seigmanager --out seigmanager/seigmanager.go
    11  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/stake/RootChainRegistry.sol --pkg rootchainregistry --out rootchainregistry/rootchainregistry.go
    12  
    13  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/stake/powerton/PowerTON.sol --pkg powerton --out powerton/powerton.go
    14  
    15  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/RequestableSimpleToken.sol --pkg token --out token/token.go
    16  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/node_modules/openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol --pkg mintabletoken --out mintabletoken/mintabletoken.go
    17  
    18  //go:generate ../../build/bin/abigen --sol plasma-evm-cotracts/contracts/EtherToken.sol --pkg ethertoken --out ethertoken/ethertoken.go
    19  
    20  import (
    21  	"context"
    22  	"errors"
    23  	"fmt"
    24  	"math/big"
    25  	"time"
    26  
    27  	"github.com/Onther-Tech/plasma-evm/accounts/abi/bind"
    28  	"github.com/Onther-Tech/plasma-evm/common"
    29  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/depositmanager"
    30  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/epochhandler"
    31  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/ethertoken"
    32  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/mintabletoken"
    33  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/powerton"
    34  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/rootchain"
    35  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/rootchainregistry"
    36  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/seigmanager"
    37  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/submithandler"
    38  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/ton"
    39  	"github.com/Onther-Tech/plasma-evm/contracts/plasma/wton"
    40  	"github.com/Onther-Tech/plasma-evm/core"
    41  	"github.com/Onther-Tech/plasma-evm/core/rawdb"
    42  	"github.com/Onther-Tech/plasma-evm/core/types"
    43  	"github.com/Onther-Tech/plasma-evm/ethclient"
    44  	"github.com/Onther-Tech/plasma-evm/log"
    45  	"github.com/Onther-Tech/plasma-evm/params"
    46  )
    47  
    48  func DeployPlasmaContracts(opt *bind.TransactOpts, backend *ethclient.Client, staminaConfig *params.StaminaConfig, tonAddress common.Address, withPETH bool, development bool, NRELength *big.Int) (common.Address, *core.Genesis, error) {
    49  	operator := opt.From
    50  	var (
    51  		tx  *types.Transaction
    52  		err error
    53  	)
    54  
    55  	dummyDB := rawdb.NewMemoryDatabase()
    56  	defer dummyDB.Close()
    57  
    58  	genesis := core.DefaultGenesisBlock(common.Address{}, operator, staminaConfig)
    59  
    60  	if withPETH {
    61  		genesis.Alloc[operator] = core.GenesisAccount{Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}
    62  	}
    63  
    64  	dummyBlock := genesis.ToBlock(dummyDB)
    65  
    66  	// 1. deploy TON
    67  	if (tonAddress != common.Address{}) {
    68  		log.Info("Use already deployed TON contract", "address", tonAddress)
    69  	} else {
    70  		tonAddress, tx, _, err = mintabletoken.DeployERC20Mintable(opt, backend)
    71  		if err != nil {
    72  			return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy MintableToken contract: %v", err))
    73  		}
    74  		log.Info("Deploy MintableToken contract", "hash", tx.Hash(), "address", tonAddress)
    75  
    76  		log.Info("Wait until deploy transaction is mined")
    77  		if err := WaitTx(backend, tx.Hash()); err != nil {
    78  			return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy MintableToken contract: %v", err))
    79  		}
    80  		increaseNonce(opt)
    81  	}
    82  
    83  	// 2. deploy EtherToken
    84  	etherTokenContract, tx, etherToken, err := ethertoken.DeployEtherToken(opt, backend, development, tonAddress, false)
    85  	if err != nil {
    86  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy EtherToken contract: %v", err))
    87  	}
    88  	log.Info("Deploy EtherToken contract", "hash", tx.Hash(), "address", etherTokenContract)
    89  
    90  	log.Info("Wait until deploy transaction is mined")
    91  	if err := WaitTx(backend, tx.Hash()); err != nil {
    92  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy EtherToken contract: %v", err))
    93  	}
    94  
    95  	// 3. deploy EpochHandler
    96  	epochHandlerContract, tx, _, err := epochhandler.DeployEpochHandler(opt, backend)
    97  	if err != nil {
    98  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy EpochHandler contract: %v", err))
    99  	}
   100  	log.Info("Deploy EpochHandler contract", "hash", tx.Hash(), "address", epochHandlerContract)
   101  
   102  	log.Info("Wait until deploy transaction is mined")
   103  	if err := WaitTx(backend, tx.Hash()); err != nil {
   104  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy EpochHandler contract: %v", err))
   105  	}
   106  	increaseNonce(opt)
   107  
   108  	// 4. deploy SubmitHandler
   109  	submitHandlerContract, tx, _, err := submithandler.DeploySubmitHandler(opt, backend, epochHandlerContract)
   110  	if err != nil {
   111  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy SubmitHandler contract: %v", err))
   112  	}
   113  	log.Info("Deploy EpochHandler contract", "hash", tx.Hash(), "address", epochHandlerContract)
   114  
   115  	log.Info("Wait until deploy transaction is mined")
   116  	if err := WaitTx(backend, tx.Hash()); err != nil {
   117  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy EpochHandler contract: %v", err))
   118  	}
   119  
   120  	// 5. deploy RootChain
   121  	rootchainContract, tx, _, err := rootchain.DeployRootChain(opt, backend, epochHandlerContract, submitHandlerContract, etherTokenContract, development, NRELength, dummyBlock.Root(), dummyBlock.TxHash(), dummyBlock.ReceiptHash())
   122  	if err != nil {
   123  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy RootChain contract: %v", err))
   124  	}
   125  	log.Info("Deploy RootChain contract", "hash", tx.Hash(), "address", rootchainContract)
   126  	if err := WaitTx(backend, tx.Hash()); err != nil {
   127  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to deploy RootChain contract: %v", err))
   128  	}
   129  	increaseNonce(opt)
   130  
   131  	// 6. initialize EtherToken
   132  	tx, err = etherToken.Init(opt, rootchainContract)
   133  	if err != nil {
   134  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to initialize EtherToken: %v", err))
   135  	}
   136  	log.Info("Initialize EtherToken", "hash", tx.Hash())
   137  	if err := WaitTx(backend, tx.Hash()); err != nil {
   138  		return common.Address{}, nil, errors.New(fmt.Sprintf("Failed to initialize EtherToken: %v", err))
   139  	}
   140  	increaseNonce(opt)
   141  
   142  	genesis.ExtraData = rootchainContract[:]
   143  
   144  	return rootchainContract, genesis, nil
   145  }
   146  
   147  type seigManagerSetter interface {
   148  	SetSeigManager(opts *bind.TransactOpts, _seigManager common.Address) (*types.Transaction, error)
   149  	SeigManager(opts *bind.CallOpts) (common.Address, error)
   150  }
   151  
   152  func increaseNonce(opt *bind.TransactOpts) {
   153  	if opt.Nonce != nil {
   154  		opt.Nonce = new(big.Int).Add(opt.Nonce, big.NewInt(1))
   155  	}
   156  }
   157  
   158  func DeployManagers(
   159  	opt *bind.TransactOpts,
   160  	backend *ethclient.Client,
   161  	withdrawalDelay *big.Int,
   162  	seigPerBlock *big.Int,
   163  	_tonAddr common.Address,
   164  	_wtonAddr common.Address,
   165  ) (
   166  	tonAddr common.Address,
   167  	wtonAddr common.Address,
   168  	registryAddr common.Address,
   169  	depositManagerAddr common.Address,
   170  	seigManagerAddr common.Address,
   171  	err error,
   172  ) {
   173  	var (
   174  		TON  *ton.TON
   175  		WTON *wton.WTON
   176  		//registry       *stakingmanager.RootChainRegistry
   177  		depositManager *depositmanager.DepositManager
   178  		//seigManager    *stakingmanager.SeigManager
   179  
   180  		tx *types.Transaction
   181  	)
   182  
   183  	// 1. deploy TON
   184  	log.Info("1. deploy TON contract")
   185  	if (_tonAddr == common.Address{}) {
   186  		if tonAddr, tx, TON, err = ton.DeployTON(opt, backend); err != nil {
   187  			err = errors.New(fmt.Sprintf("Failed to deploy TON: %v", err))
   188  			return
   189  		}
   190  
   191  		if err = WaitTx(backend, tx.Hash()); err != nil {
   192  			err = errors.New(fmt.Sprintf("Failed to deploy TON: %v", err))
   193  			return
   194  		}
   195  
   196  		log.Info("TON deployed", "addr", tonAddr.String(), "tx", tx.Hash())
   197  		increaseNonce(opt)
   198  	} else {
   199  		tonAddr = _tonAddr
   200  		log.Warn("use already deployed TON", "addr", tonAddr.String())
   201  		if TON, err = ton.NewTON(tonAddr, backend); err != nil {
   202  			err = errors.New(fmt.Sprintf("Failed to instantiate TON: %v", err))
   203  			return
   204  		}
   205  	}
   206  
   207  	// 2. deploy WTON
   208  	log.Info("2. deploy WTON contract")
   209  	if (_wtonAddr == common.Address{}) {
   210  		if wtonAddr, tx, WTON, err = wton.DeployWTON(opt, backend, tonAddr); err != nil {
   211  			err = errors.New(fmt.Sprintf("Failed to deploy WTON: %v", err))
   212  			return
   213  		}
   214  
   215  		if err = WaitTx(backend, tx.Hash()); err != nil {
   216  			err = errors.New(fmt.Sprintf("Failed to deploy WTON: %v", err))
   217  			return
   218  		}
   219  		log.Info("WTON deployed", "addr", wtonAddr.String(), "tx", tx.Hash())
   220  		increaseNonce(opt)
   221  	} else {
   222  		wtonAddr = _wtonAddr
   223  		log.Warn("use already deployed WTON", "addr", wtonAddr.String())
   224  		if WTON, err = wton.NewWTON(wtonAddr, backend); err != nil {
   225  			err = errors.New(fmt.Sprintf("Failed to instantiate WTON: %v", err))
   226  			return
   227  		}
   228  	}
   229  
   230  	if addr, _ := WTON.SeigManager(&bind.CallOpts{Pending: false}); (addr != common.Address{}) {
   231  		err = errors.New("WTON already set SeigManager")
   232  		return
   233  	}
   234  
   235  	// 3. deploy RootChainRegistry
   236  	log.Info("3. deploy RootChainRegistry")
   237  	if registryAddr, tx, _, err = rootchainregistry.DeployRootChainRegistry(opt, backend); err != nil {
   238  		err = errors.New(fmt.Sprintf("Failed to deploy RootChainRegistry: %v", err))
   239  		return
   240  	}
   241  
   242  	if err = WaitTx(backend, tx.Hash()); err != nil {
   243  		err = errors.New(fmt.Sprintf("Failed to deploy RootChainRegistry: %v", err))
   244  		return
   245  	}
   246  	log.Info("RootChainRegistry deployed", "addr", registryAddr.String(), "tx", tx.Hash())
   247  	increaseNonce(opt)
   248  
   249  	// 4. deploy DepositManager
   250  	log.Info("4. deploy DepositManager")
   251  	if depositManagerAddr, tx, depositManager, err = depositmanager.DeployDepositManager(opt, backend, wtonAddr, registryAddr, withdrawalDelay); err != nil {
   252  		err = errors.New(fmt.Sprintf("Failed to deploy DepositManager: %v", err))
   253  		return
   254  	}
   255  
   256  	if err = WaitTx(backend, tx.Hash()); err != nil {
   257  		err = errors.New(fmt.Sprintf("Failed to deploy DepositManager: %v", err))
   258  		return
   259  	}
   260  	log.Info("DepositManager deployed", "addr", depositManagerAddr.String(), "tx", tx.Hash())
   261  	increaseNonce(opt)
   262  
   263  	// 5. deploy SeigManager
   264  	log.Info("5. deploy SeigManager")
   265  	if seigManagerAddr, tx, _, err = seigmanager.DeploySeigManager(opt, backend, tonAddr, wtonAddr, registryAddr, depositManagerAddr, seigPerBlock); err != nil {
   266  		err = errors.New(fmt.Sprintf("Failed to deploy SeigManager: %v", err))
   267  		return
   268  	}
   269  
   270  	if err = WaitTx(backend, tx.Hash()); err != nil {
   271  		err = errors.New(fmt.Sprintf("Failed to deploy SeigManager: %v", err))
   272  		return
   273  	}
   274  	log.Info("SeigManager deployed", "addr", seigManagerAddr.String(), "tx", tx.Hash())
   275  	increaseNonce(opt)
   276  
   277  	// 6. add TON minter role to SeigManager
   278  	log.Info("6. add WTON minter role to SeigManager")
   279  	if ok, _ := WTON.IsMinter(&bind.CallOpts{Pending: false}, seigManagerAddr); ok {
   280  		log.Info("Already minter role provided")
   281  	} else {
   282  		if tx, err = WTON.AddMinter(opt, seigManagerAddr); err != nil {
   283  			err = errors.New(fmt.Sprintf("Failed to add WTON minter role to SeigManager: %v", err))
   284  			return
   285  		}
   286  		if err = WaitTx(backend, tx.Hash()); err != nil {
   287  			err = errors.New(fmt.Sprintf("Failed to add WTON minter role to SeigManager: %v", err))
   288  			return
   289  		}
   290  		log.Info("Set WTON minter to SeigManager", "tx", tx.Hash())
   291  		increaseNonce(opt)
   292  	}
   293  
   294  	// 7. add WTON minter role to SeigManager
   295  	log.Info("7. add TON minter role to WTON")
   296  	if ok, _ := TON.IsMinter(&bind.CallOpts{Pending: false}, wtonAddr); ok {
   297  		log.Info("Already minter role provided")
   298  	} else {
   299  		if tx, err = TON.AddMinter(opt, wtonAddr); err != nil {
   300  			err = errors.New(fmt.Sprintf("Failed to add TON minter role to WTON: %v", err))
   301  			return
   302  		}
   303  		if err = WaitTx(backend, tx.Hash()); err != nil {
   304  			err = errors.New(fmt.Sprintf("Failed to add TON minter role to WTON: %v", err))
   305  			return
   306  		}
   307  		log.Info("Set TON minter to WTON", "tx", tx.Hash())
   308  		increaseNonce(opt)
   309  	}
   310  
   311  	// 8. set seig manager to contracts
   312  	var contracts = []seigManagerSetter{depositManager, WTON}
   313  	targets := []string{"DepositManager", "WTON"}
   314  
   315  	log.Info("8. Setting SeigManager address to target contracts", "targets", targets)
   316  	for i, c := range contracts {
   317  		target := targets[i]
   318  
   319  		if tx, err = c.SetSeigManager(opt, seigManagerAddr); err != nil {
   320  			err = errors.New(fmt.Sprintf("Failed to set SeigManager to %s: %v", target, err))
   321  			return
   322  		}
   323  		if err = WaitTx(backend, tx.Hash()); err != nil {
   324  			err = errors.New(fmt.Sprintf("Failed to set SeigManager to %s: %v", target, err))
   325  			return
   326  		}
   327  
   328  		log.Info("Set SeigManager to target cotnract", "target", target, "tx", tx.Hash())
   329  		increaseNonce(opt)
   330  	}
   331  
   332  	return
   333  }
   334  
   335  func DeployPowerTON(
   336  	opt *bind.TransactOpts,
   337  	backend *ethclient.Client,
   338  	wtonAddr common.Address,
   339  	seigManagerAddr common.Address,
   340  	roundDuration *big.Int,
   341  ) (
   342  	powertonAddr common.Address,
   343  	err error,
   344  ) {
   345  	seigManager, err := seigmanager.NewSeigManager(seigManagerAddr, backend)
   346  	if err != nil {
   347  		return
   348  	}
   349  
   350  	// 1. deploy PowerTON
   351  	powertonAddr, tx, pton, err := powerton.DeployPowerTON(opt, backend, seigManagerAddr, wtonAddr, roundDuration)
   352  	log.Info("1. deploy PowerTON", "address", powertonAddr, "tx", tx.Hash())
   353  	if err != nil {
   354  		err = errors.New(fmt.Sprintf("Failed to deploy PowerTON: %v", err))
   355  		return
   356  	}
   357  
   358  	err = WaitTx(backend, tx.Hash())
   359  	if err != nil {
   360  		err = errors.New(fmt.Sprintf("Failed to deploy PowerTON: %v", err))
   361  		return
   362  	}
   363  	increaseNonce(opt)
   364  
   365  	// 2. initialize PowerTON
   366  	tx, err = pton.Init(opt)
   367  	log.Info("2. initialize PowerTON", "tx", tx.Hash())
   368  	if err != nil {
   369  		err = errors.New(fmt.Sprintf("Failed to initialize PowerTON: %v", err))
   370  		return
   371  	}
   372  	err = WaitTx(backend, tx.Hash())
   373  	if err != nil {
   374  		err = errors.New(fmt.Sprintf("Failed to initialize PowerTON: %v", err))
   375  		return
   376  	}
   377  	increaseNonce(opt)
   378  
   379  	// 3. set PowerTON to SeigManager
   380  	log.Info("3. set PowerTON to SeigManager", "SeigManager", seigManagerAddr, "PowerTON", powertonAddr, "tx", tx.Hash())
   381  	tx, err = seigManager.SetPowerTON(opt, powertonAddr)
   382  	if err != nil {
   383  		err = errors.New(fmt.Sprintf("Failed to set PowerTON to SeigManager: %v", err))
   384  		return
   385  	}
   386  	err = WaitTx(backend, tx.Hash())
   387  	if err != nil {
   388  		err = errors.New(fmt.Sprintf("Failed to set PowerTON to SeigManager: %v", err))
   389  		return
   390  	}
   391  	increaseNonce(opt)
   392  
   393  	return
   394  }
   395  
   396  func WaitTx(backend *ethclient.Client, hash common.Hash) error {
   397  	var receipt *types.Receipt
   398  
   399  	<-time.NewTimer(1 * time.Second).C
   400  
   401  	for receipt, _ = backend.TransactionReceipt(context.Background(), hash); receipt == nil; {
   402  		<-time.NewTimer(1 * time.Second).C
   403  
   404  		receipt, _ = backend.TransactionReceipt(context.Background(), hash)
   405  	}
   406  
   407  	if receipt.Status == 0 {
   408  		return errors.New(fmt.Sprintf("Transaction reverted: %s", receipt.TxHash.String()))
   409  	}
   410  	return nil
   411  }