Skip to content

Commit

Permalink
Deploy NFT contracts (#1322)
Browse files Browse the repository at this point in the history
* Deploy NFT contracts

* Provide flags for existing tokens on the root chain

* Linters fix
  • Loading branch information
Stefan-Ethernal authored Apr 4, 2023
1 parent 0972756 commit afee1c6
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 66 deletions.
20 changes: 20 additions & 0 deletions command/genesis/polybft_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,26 @@ func (p *genesisParams) deployContracts(totalStake *big.Int) (map[types.Address]
artifact: contractsapi.ChildERC20Predicate,
address: contracts.ChildERC20PredicateContract,
},
{
// ChildERC721 token contract
artifact: contractsapi.ChildERC721,
address: contracts.ChildERC721Contract,
},
{
// ChildERC721Predicate token contract
artifact: contractsapi.ChildERC721Predicate,
address: contracts.ChildERC721PredicateContract,
},
{
// ChildERC1155 contract
artifact: contractsapi.ChildERC1155,
address: contracts.ChildERC1155Contract,
},
{
// ChildERC1155Predicate token contract
artifact: contractsapi.ChildERC1155Predicate,
address: contracts.ChildERC1155PredicateContract,
},
{
// BLS contract
artifact: contractsapi.BLS,
Expand Down
134 changes: 104 additions & 30 deletions command/rootchain/initcontracts/init_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,18 @@ import (
const (
contractsDeploymentTitle = "[ROOTCHAIN - CONTRACTS DEPLOYMENT]"

stateSenderName = "StateSender"
checkpointManagerName = "CheckpointManager"
blsName = "BLS"
bn256G2Name = "BN256G2"
exitHelperName = "ExitHelper"
rootERC20PredicateName = "RootERC20Predicate"
rootERC20Name = "RootERC20"
erc20TemplateName = "ERC20Template"
stateSenderName = "StateSender"
checkpointManagerName = "CheckpointManager"
blsName = "BLS"
bn256G2Name = "BN256G2"
exitHelperName = "ExitHelper"
rootERC20PredicateName = "RootERC20Predicate"
rootERC20Name = "RootERC20"
erc20TemplateName = "ERC20Template"
rootERC721PredicateName = "RootERC721Predicate"
rootERC721Name = "RootERC721"
rootERC1155PredicateName = "RootERC1155Predicate"
rootERC1155Name = "RootERC1155"
)

var (
Expand Down Expand Up @@ -61,6 +65,18 @@ var (
erc20TemplateName: func(rootchainConfig *polybft.RootchainConfig, addr types.Address) {
rootchainConfig.ERC20TemplateAddress = addr
},
rootERC721PredicateName: func(rootchainConfig *polybft.RootchainConfig, addr types.Address) {
rootchainConfig.RootERC721PredicateAddress = addr
},
rootERC721Name: func(rootchainConfig *polybft.RootchainConfig, addr types.Address) {
rootchainConfig.RootERC721Address = addr
},
rootERC1155PredicateName: func(rootchainConfig *polybft.RootchainConfig, addr types.Address) {
rootchainConfig.RootERC1155PredicateAddress = addr
},
rootERC1155Name: func(rootchainConfig *polybft.RootchainConfig, addr types.Address) {
rootchainConfig.RootERC1155Address = addr
},
}
)

Expand Down Expand Up @@ -96,9 +112,23 @@ func GetCommand() *cobra.Command {

cmd.Flags().StringVar(
&params.rootERC20TokenAddr,
rootchainERC20Flag,
erc20AddrFlag,
"",
"existing root chain ERC 20 token address",
)

cmd.Flags().StringVar(
&params.rootERC721TokenAddr,
erc721AddrFlag,
"",
"existing root chain ERC20 token address",
"existing root chain ERC 721 token address",
)

cmd.Flags().StringVar(
&params.rootERC1155TokenAddr,
erc1155AddrFlag,
"",
"existing root chain ERC 1155 token address",
)

cmd.Flags().BoolVar(
Expand Down Expand Up @@ -198,57 +228,79 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client,

deployContracts := []*contractInfo{
{
name: "StateSender",
name: stateSenderName,
artifact: contractsapi.StateSender,
},
{
name: "CheckpointManager",
name: checkpointManagerName,
artifact: contractsapi.CheckpointManager,
},
{
name: "BLS",
name: blsName,
artifact: contractsapi.BLS,
},
{
name: "BN256G2",
name: bn256G2Name,
artifact: contractsapi.BLS256,
},
{
name: "ExitHelper",
name: exitHelperName,
artifact: contractsapi.ExitHelper,
},
{
name: "RootERC20Predicate",
name: rootERC20PredicateName,
artifact: contractsapi.RootERC20Predicate,
},
{
name: "ERC20Template",
name: erc20TemplateName,
artifact: contractsapi.ChildERC20,
},
{
name: rootERC721PredicateName,
artifact: contractsapi.RootERC721Predicate,
},
{
name: rootERC1155PredicateName,
artifact: contractsapi.RootERC1155Predicate,
},
}
rootchainConfig := &polybft.RootchainConfig{}
manifest.RootchainConfig = rootchainConfig

if params.rootERC20TokenAddr != "" {
// use existing root chain ERC20 token
addr := types.StringToAddress(params.rootERC20TokenAddr)

code, err := client.Eth().GetCode(ethgo.Address(addr), ethgo.Latest)
if err != nil {
return fmt.Errorf("failed to check is root chain ERC20 token deployed: %w", err)
} else if code == "0x" {
return fmt.Errorf("root chain ERC20 token is not deployed on provided address %s", params.rootERC20TokenAddr)
if err := populateExistingTokenAddr(client.Eth(),
params.rootERC20TokenAddr, rootERC20Name, manifest); err != nil {
return err
}
} else {
// deploy MockERC20 as a default root chain ERC20 token
deployContracts = append(deployContracts,
&contractInfo{name: rootERC20Name, artifact: contractsapi.RootERC20})
}

populatorFn, ok := metadataPopulatorMap["RootERC20"]
if !ok {
return fmt.Errorf("root chain metadata populator not registered for contract 'RootERC20'")
if params.rootERC721TokenAddr != "" {
// use existing root chain ERC721 token
if err := populateExistingTokenAddr(client.Eth(),
params.rootERC721TokenAddr, rootERC721Name, manifest); err != nil {
return err
}
} else {
// deploy MockERC721 as a default root chain ERC721 token
deployContracts = append(deployContracts,
&contractInfo{name: rootERC721Name, artifact: contractsapi.RootERC721})
}

populatorFn(manifest.RootchainConfig, addr)
if params.rootERC1155TokenAddr != "" {
// use existing root chain ERC1155 token
if err := populateExistingTokenAddr(client.Eth(),
params.rootERC1155TokenAddr, rootERC1155Name, manifest); err != nil {
return err
}
} else {
// deploy MockERC20 as default root chain ERC20 token
deployContracts = append(deployContracts, &contractInfo{name: "RootERC20", artifact: contractsapi.RootERC20})
// deploy MockERC1155 as a default root chain ERC1155 token
deployContracts = append(deployContracts,
&contractInfo{name: rootERC1155Name, artifact: contractsapi.RootERC1155})
}

for _, contract := range deployContracts {
Expand Down Expand Up @@ -312,6 +364,28 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client,
return nil
}

// populateExistingTokenAddr checks whether given token is deployed on the provided address.
// If it is, then its address is set to the rootchain config, otherwise an error is returned
func populateExistingTokenAddr(eth *jsonrpc.Eth, tokenAddr, tokenName string, manifest *polybft.Manifest) error {
addr := types.StringToAddress(tokenAddr)

code, err := eth.GetCode(ethgo.Address(addr), ethgo.Latest)
if err != nil {
return fmt.Errorf("failed to check is %s token deployed: %w", tokenName, err)
} else if code == "0x" {
return fmt.Errorf("%s token is not deployed on provided address %s", tokenName, tokenAddr)
}

populatorFn, ok := metadataPopulatorMap[tokenName]
if !ok {
return fmt.Errorf("root chain metadata populator not registered for contract '%s'", tokenName)
}

populatorFn(manifest.RootchainConfig, addr)

return nil
}

// initializeCheckpointManager invokes initialize function on "CheckpointManager" smart contract
func initializeCheckpointManager(
o command.OutputFormatter,
Expand Down
22 changes: 13 additions & 9 deletions command/rootchain/initcontracts/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@ import (
)

const (
manifestPathFlag = "manifest"
deployerKeyFlag = "deployer-key"
jsonRPCFlag = "json-rpc"
rootchainERC20Flag = "rootchain-erc20"
manifestPathFlag = "manifest"
deployerKeyFlag = "deployer-key"
jsonRPCFlag = "json-rpc"
erc20AddrFlag = "erc20-token"
erc721AddrFlag = "erc721-token"
erc1155AddrFlag = "erc1155-token"

defaultManifestPath = "./manifest.json"
)

type initContractsParams struct {
manifestPath string
deployerKey string
jsonRPCAddress string
rootERC20TokenAddr string
isTestMode bool
manifestPath string
deployerKey string
jsonRPCAddress string
rootERC20TokenAddr string
rootERC721TokenAddr string
rootERC1155TokenAddr string
isTestMode bool
}

func (ip *initContractsParams) validateFlags() error {
Expand Down
36 changes: 34 additions & 2 deletions consensus/polybft/contractsapi/artifacts-gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ func main() {
"child/ChildERC20Predicate.sol",
"ChildERC20Predicate",
},
{
"child/ChildERC721.sol",
"ChildERC721",
},
{
"child/ChildERC721Predicate.sol",
"ChildERC721Predicate",
},
{
"child/ChildERC1155.sol",
"ChildERC1155",
},
{
"child/ChildERC1155Predicate.sol",
"ChildERC1155Predicate",
},
{
"child/System.sol",
"System",
Expand Down Expand Up @@ -79,13 +95,29 @@ func main() {
"root/StateSender.sol",
"StateSender",
},
{
"mocks/MockERC20.sol",
"MockERC20",
},
{
"root/RootERC20Predicate.sol",
"RootERC20Predicate",
},
{
"mocks/MockERC20.sol",
"MockERC20",
"mocks/MockERC721.sol",
"MockERC721",
},
{
"root/RootERC721Predicate.sol",
"RootERC721Predicate",
},
{
"mocks/MockERC1155.sol",
"MockERC1155",
},
{
"root/RootERC1155Predicate.sol",
"RootERC1155Predicate",
},
}

Expand Down
10 changes: 9 additions & 1 deletion consensus/polybft/contractsapi/gen_sc_data.go

Large diffs are not rendered by default.

Loading

0 comments on commit afee1c6

Please sign in to comment.