diff --git a/bnb-smart-chain/developers/rpc/index.html b/bnb-smart-chain/developers/rpc/index.html index 6520698024..52ce4ec0ae 100644 --- a/bnb-smart-chain/developers/rpc/index.html +++ b/bnb-smart-chain/developers/rpc/index.html @@ -2171,6 +2171,7 @@

BSC Mainnet (ChainID 0x38, 56 in
  • https://bsc-dataseed.ninicoin.io
  • https://bsc.nodereal.io
  • https://bsc-dataseed-public.bnbchain.org
  • +
  • https://bnb.rpc.subquery.network/public
  • You could find more endpoints from here.

    BSC Testnet (ChainID 0x61, 97 in decimal)

    @@ -2211,6 +2212,9 @@

    RPC Providers

    dRPC: https://drpc.org/chainlist/bsc

    +
  • +

    SubQuery: https://rpc.subquery.network/56)

    +
  • Starting HTTP JSON-RPC

    You can start the HTTP JSON-RPC with the –http flag diff --git a/search/search_index.json b/search/search_index.json index c72a8a91ac..b585dbfbf0 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"BNB Chain","text":""},{"location":"#bnb-chain-empowering-the-future-of-decentralized-applications","title":"BNB Chain: Empowering the Future of Decentralized Applications","text":"

    BNB Chain is a leading blockchain ecosystem designed to support the growing demands of the decentralized web (Web3). Offering a unique combination of speed, scalability, and affordability, BNB Chain has become a popular choice for developers building decentralized applications (DApps) and for users seeking to participate in the world of decentralized finance (DeFi).

    "},{"location":"#key-features-and-benefits","title":"Key Features and Benefits","text":""},{"location":"#chains","title":"Chains","text":"

    BNB Chain is composed of three blockchains - BNB Smart Chain (BSC), opBNB and BNB Greenfield. Powering and coordinating the ecosystem is the BNB token. Along with fueling transactions on BNB Chain, the BNB token also acts as a governance token. Within this ecosystem, the ownership, usage, and monetization of data are possible for all users and participants in the BNB Chain ecosystem.

    BNB Smart Chain (BSC)

    BNB Smart Chain (BSC) is a high-performance blockchain platform designed to enable the development of scalable and user-friendly decentralized applications (DApps). As a core component of the BNB Chain ecosystem, BSC offers a robust infrastructure for building a wide range of applications, particularly in the decentralized finance (DeFi) space.

    opBNB

    A layer-2 scaling solution for BNB Smart Chain that significantly increases transaction speed and reduces fees. It achieves this by leveraging Optimistic Rollups technology, making BNB Chain even more suitable for high-throughput applications.

    BNB Greenfield

    A decentralized storage infrastructure designed to provide a secure and scalable platform for storing and managing data on the blockchain. It enables users to store files, NFTs, and other digital assets in a decentralized manner, promoting data ownership and control.

    Join BNB Ecosystem

    Share your project with BNB Chain Ecosystem or seeking for cooperations. We want to make it as easy as possible for prjects to get more exposure in BNB Chain Ecosystem or ask for support from the team.

    "},{"location":"#use-cases","title":"Use Cases","text":""},{"location":"#quick-start","title":"Quick Start","text":"BNB Smart Chain

    Getting Started with high performance Layer1 particularly for decentralized finance (DeFi)

    opBNB

    Getting Started with Layer2 scaling solution on BNB Chain ecosystem

    BNB Greenfield

    Getting Started with cutting-edge decentralized storage

    "},{"location":"announce/","title":"Announcements","text":""},{"location":"announce/#announcement","title":"Announcement","text":"Greenfield Mongolian Hardfork (Testnet) Bugfixing on Greenfield Testnet 2024 July 31 Greenfield Mongolian Hardfork (Mainnet) Bugfixing on Greenfield Mainnet 2024 August 8"},{"location":"announce/feynman-bsc/","title":"Feynman Hardfork(BSC)","text":""},{"location":"announce/feynman-bsc/#feynman-upgrade-of-bsc","title":"Feynman Upgrade of BSC","text":"Hardfork"},{"location":"announce/feynman-bsc/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Haber upgrade will happen at:

    "},{"location":"announce/feynman-bsc/#upgrade-to-bsc-node-v1313-before-hardfork","title":"Upgrade to BSC Node v1.3.13 Before Hardfork","text":"

    Feyman upgrade is the most important milestone of BNB Chain Fusion. The BNB Chain Fusion is a strategic shift to migrate the Beacon Chain\u2019s functionalities to BNB Smart Chain (BSC) and retire Beacon Chain. This move aims to streamline the network, improve efficiency, reduce security risks, and align BNB Chain\u2019s architecture with the current technological demands and future growth. BEP333 propose to securely and smoothly transit the BNB Beacon Chain and BNB Smart Chain (BSC) from a dual-chain structure into a single chain structure and thus decommission the Beacon Chain.

    Due to Feyman\u2019s upgrade, it will have a significant impact on the BNB ecosystem. We welcome the community to submit issues on GitHub or Discord. Kindly remind that BNB Chain has a bug bounty program if anyone find any security issues.

    "},{"location":"announce/feynman-bsc/#key-highlight","title":"Key Highlight","text":"

    BEP-294, BEP-297 and BEP-299 will be deployed in the BSC Feynman hard fork.

    "},{"location":"announce/final-sunset-bc-testnet/","title":"Final Sunset Hardfork(BC testnet)","text":""},{"location":"announce/final-sunset-bc-testnet/#final-sunset-hardfork-of-bc-testnet","title":"Final Sunset Hardfork of BC Testnet","text":"Hardfork"},{"location":"announce/final-sunset-bc-testnet/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Final Sunset Hardfork will happen at:

    "},{"location":"announce/final-sunset-bc-testnet/#upgrade-to-bc-node-v01023-before-hardfork","title":"Upgrade to BC Node v0.10.23 Before Hardfork","text":"

    BC node need to be upgraded before the hardfork time.

    "},{"location":"announce/final-sunset-bc-testnet/#upgrade-instructions","title":"Upgrade Instructions","text":"

    As a fullnode runner, you need to take the following steps before the hardfork block height.

    1) Download the new v0.10.23 binary and replace the previous version.

    2) Download the new config file app.toml to replace the previous version or add the following under the [upgrade] module of app.toml.

    FinalSunsetHeight = 56218686\n

    3) Stop the bnbchaind process and restart it with v0.10.23.

    service bnbchaind restart\n
    "},{"location":"announce/final-sunset-bc-testnet/#key-highlight","title":"Key Highlight","text":"

    After Final Sunset, the cross-chain communication between the Beacon Chain and BSC will be completely stopped. The validators in the Beacon Chain community will gradually shut down, and the entire chain will no longer accept new transactions or propose new blocks. For more information about BNB Chain Fusion, please refer to this.

    "},{"location":"announce/haber-bsc/","title":"Haber Hardfork(BSC)","text":""},{"location":"announce/haber-bsc/#haber-upgrade-of-bsc","title":"Haber Upgrade of BSC","text":"Hardfork"},{"location":"announce/haber-bsc/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Haber upgrade will happen at:

    "},{"location":"announce/haber-bsc/#upgrade-to-bsc-node-v148-before-hardfork","title":"Upgrade to BSC Node v1.4.8 Before Hardfork","text":"

    Release v1.4.8 is a cut-in hard fork release for BSC Testnet and Mainnet, the HF name is: Haber, it only supports one BEP: BEP-381: Precompile for secp256r1 Curve Support

    "},{"location":"announce/haber-bsc/#key-highlight-eip-7212-secp256r1-curve-precompile","title":"Key Highlight: EIP 7212 - secp256r1 Curve Precompile","text":"

    BSC would use address 0x100 as secp256r1 pre-compile contract, which is same as other major chains to make it easier for developers. Developers may refer this code on how to use this pre-compile contract: https://github.com/getclave/clave-contracts/blob/master/contracts/helpers/VerifierCaller.sol , which is same as other major chains to make it easier for developers.

    "},{"location":"announce/haber-bsc/#key-highlight-bep-336-enable-blob-carrying-transaction-for-bsc","title":"Key Highlight: BEP 336 - Enable Blob Carrying Transaction for BSC","text":"

    Introduce a new transaction format for \u201cblob-carrying transactions\u201d which contain a large amount of data that cannot be accessed by EVM execution, but whose commitment can be accessed. The format is intended to be fully compatible with the format that will be used in full sharding.

    "},{"location":"announce/haber-opbnb/","title":"Haber Hardfork(opBNB)","text":""},{"location":"announce/haber-opbnb/#haber-upgrade-of-opbnb","title":"Haber Upgrade of opBNB","text":"Hardfork"},{"location":"announce/haber-opbnb/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Haber upgrade will happen at:

    "},{"location":"announce/haber-opbnb/#upgrade-to-opbnb-node-v042-before-hardfork","title":"Upgrade to opBNB Node v0.4.2 Before Hardfork","text":"

    op-node and op-geth need to be upgraded before the hardfork time.

    "},{"location":"announce/haber-opbnb/#key-highlight-eip-7212-secp256r1-curve-precompile","title":"Key Highlight: EIP 7212 - secp256r1 Curve Precompile","text":"

    One of the significant enhancements in this release is the introduction of a precompile for the secp256r1 curve, as specified in EIP 7212. This precompile allows for efficient elliptic curve operations, which is crucial for improving the performance and security of cryptographic applications on the blockchain.

    "},{"location":"announce/haber-opbnb/#key-highlight-bep-336-switch-da-from-calldata-to-blob-of-bsc","title":"Key Highlight: BEP 336 - Switch DA from calldata to blob of BSC","text":"

    DA data will be submitted to the BSC network in blob format. Regular BSC nodes only retain blob data from the past 18 days. If you are syncing data from the genesis block or are more than 18 days behind the latest block, you will need to ensure that your configured L1 endpoint supports persisting blob data for a longer period of time. We will ensure that the Testnet snapshot provided by this snapshot repository is within the 18-day range, so you can also choose to use the snapshot to avoid relying on older blob data to start your new node.

    "},{"location":"announce/mongolian-greenfield/","title":"Mongolian Hardfork(Greenfield)","text":""},{"location":"announce/mongolian-greenfield/#mongolian-upgrade-of-greenfield","title":"Mongolian Upgrade of Greenfield","text":"Hardfork"},{"location":"announce/mongolian-greenfield/#upgrade-timeline","title":"Upgrade Timeline","text":""},{"location":"announce/mongolian-greenfield/#validators-and-sps-should-complete-upgrading-to-the-latest-version-before-hardfork","title":"Validators and SPs should complete upgrading to the latest version before hardfork:","text":"

    For Validators: greenfield v1.9.0

    For SPs: greenfield-storage-provider v1.9.0

    "},{"location":"announce/mongolian-greenfield/#new-features-introduced","title":"New features introduced:","text":""},{"location":"announce/mongolian-greenfield/#bug-fixing","title":"Bug fixing","text":""},{"location":"announce/mongolian-greenfield/#docs","title":"Docs","text":""},{"location":"announce/second-sunset-bc-testnet/","title":"Second Sunset Hardfork(BC testnet)","text":""},{"location":"announce/second-sunset-bc-testnet/#second-sunset-hardfork-of-bc-testnet","title":"Second Sunset Hardfork of BC Testnet","text":"Hardfork"},{"location":"announce/second-sunset-bc-testnet/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Second Sunset Hardfork will happen at:

    "},{"location":"announce/second-sunset-bc-testnet/#upgrade-to-bc-node-v01021-before-hardfork","title":"Upgrade to BC Node v0.10.21 Before Hardfork","text":"

    BC node need to be upgraded before the hardfork time.

    "},{"location":"announce/second-sunset-bc-testnet/#upgrade-instructions","title":"Upgrade Instructions","text":"

    As a fullnode runner, you need to take the following steps before the hardfork block height.

    1) Download the new v0.10.21 binary and replace the previous version.

    2) Download the new config file app.toml to replace the previous version or add the following under the [upgrade] module of app.toml.

    SecondSunsetHeight = 54554742\n

    3) Stop the bnbchaind process and restart it with v0.10.21.

    service bnbchaind restart\n
    "},{"location":"announce/second-sunset-bc-testnet/#key-highlight","title":"Key Highlight","text":"

    All TimeLocks and AtomicSwaps on BC tesnet will automatically be refunded to user accounts. All the BSC delegations will be automatically undelegated and refunded to user accounts after the unbonding period. For more information about BNB Chain Fusion, please refer to this.

    "},{"location":"announce/second-sunset-bc/","title":"Second Sunset Hardfork(BC)","text":""},{"location":"announce/second-sunset-bc/#second-sunset-hardfork-of-bc","title":"Second Sunset Hardfork of BC","text":"Hardfork"},{"location":"announce/second-sunset-bc/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Second Sunset Hardfork will happen at:

    "},{"location":"announce/second-sunset-bc/#upgrade-to-bc-node-v01022-before-hardfork","title":"Upgrade to BC Node v0.10.22 Before Hardfork","text":"

    BC node need to be upgraded before the hardfork time.

    "},{"location":"announce/second-sunset-bc/#upgrade-instructions","title":"Upgrade Instructions","text":"

    As a fullnode runner, you need to take the following steps before the hardfork block height.

    1) Download the new v0.10.22 binary and replace the previous version.

    2) Download the new config file app.toml to replace the previous version or add the following under the [upgrade] module of app.toml.

    SecondSunsetHeight = 378062790\n

    3) Stop the bnbchaind process and restart it with v0.10.22.

    service bnbchaind restart\n
    "},{"location":"announce/second-sunset-bc/#key-highlight","title":"Key Highlight","text":"

    All TimeLocks and AtomicSwaps on BC tesnet will automatically be refunded to user accounts. All the BSC delegations will be automatically undelegated and refunded to user accounts after the unbonding period. For more information about BNB Chain Fusion, please refer to this.

    "},{"location":"announce/veld-greenfield/","title":"Veld Hardfork(Greenfield)","text":""},{"location":"announce/veld-greenfield/#veld-upgrade-of-greenfield","title":"Veld Upgrade of Greenfield","text":"Hardfork"},{"location":"announce/veld-greenfield/#upgrade-timeline","title":"Upgrade Timeline","text":""},{"location":"announce/veld-greenfield/#validators-and-sps-should-complete-upgrading-to-the-latest-version-before-hardfork","title":"Validators and SPs should complete upgrading to the latest version before hardfork:","text":"

    For Validators: greenfield v1.8.0

    For SPs: greenfield-storage-provider v1.8.0

    "},{"location":"announce/veld-greenfield/#new-features-introduced","title":"New features introduced:","text":"

    No new feature is introduced.

    "},{"location":"announce/veld-greenfield/#bug-fixing","title":"Bug fixing","text":""},{"location":"bc-fusion/","title":"BNB Chain Fusion","text":"BNB Chain Fusion

    The BNB Chain Fusion is a strategic shift to migrate the BNB Beacon Chain\u2019s functionalities to BNB Smart Chain (BSC) and retire BNB Beacon Chain. This move aims to streamline the network, improve efficiency, reduce security risks, and align BNB Chain's architecture with the current technological demands and future growth.

    Roadmap

    The detailed roadmap of BNB Chain fusion.

    Stake Migration

    Migrate staking from the Beacon Chain to BSC for higher APY.

    Token Migration

    Transfer token from Beacon Chain to BSC with single click.

    Token Bind

    Bind the token between BC and BSC to enable bridge, and token recover even after the sunset of Beacon Chain.

    Participate Staking

    Stake on BSC directly to secure the network and earn BNB!

    Participate Governance

    Participate in governance on the BSC through Tally

    "},{"location":"bc-fusion/overview/","title":"Overview - BC Fusion","text":""},{"location":"bc-fusion/overview/#overview","title":"Overview","text":"

    BNB Beacon Chain is a blockchain developed by the BNB Chain community that implements a vision of a decentralized exchange (DEX) for digital assets. Besides this, Beacon Chain and BSC is a dual-chain structure: Beacon Chain helps to enhance the security of BSC as a staking and governance layer. With the rise of various other forms of Dex, order-book based decentralized exchange was decommissioned in BEP151. With the quick evolution of BSC, the Beacon Chain has become a burden. The cross-chain bridge that connects the two chains slows down the development iteration and always exposes BNB to a certain level of security vulnerabilities. It\u2019s time to take a step further and migrate the functionality of Beacon Chain to BSC, allowing Beacon Chain to retire.

    There will be several pahses to retrie Beacon Chain:

    All stakholders (e.g., token holders/owners, validators, project owners) should pay attention BNB Chain blog for releated annonuncements and take actions proactively.

    For more information about BNB Chain fusion, please refer to BEP-333.

    For the roadmap and milestons of BNB Chain fusion, please refer to the blog.

    "},{"location":"bc-fusion/developers/crosschain-redelegation/","title":"Cross Chain Redelegation","text":""},{"location":"bc-fusion/developers/crosschain-redelegation/#crosschain-redelgation","title":"Crosschain Redelgation","text":"

    To migrate the exisiting delegation from BNB Beacon chain (the old BSC staking) to the new BNB smart chain native staking, crosschain redelegation can be used. A user can submit a message called MsgSideChainStakeMigration to the Beacon chain. Underlying, it will unbound the delegation immediately on BC (without wating unbond period), sends a cross-chain transaction to BSC to delegate to a native BSC validator.

    The definition of MsgSideChainStakeMigration is as the blow.

    type MsgSideChainStakeMigration struct {\n    ValidatorSrcAddr sdk.ValAddress        `json:\"validator_src_addr\"`\n    ValidatorDstAddr sdk.SmartChainAddress `json:\"validator_dst_addr\"`\n    DelegatorAddr    sdk.SmartChainAddress `json:\"delegator_addr\"`\n    RefundAddr       sdk.AccAddress        `json:\"refund_addr\"`\n    Amount           sdk.Coin              `json:\"amount\"`\n}\n

    Be noted: please make sure input the DelegatorAddr correctly, otherwise you will lose the fund permanently.

    For more details, please refer to the codes: https://github.com/bnb-chain/bnc-cosmos-sdk/blob/bc-fusion/x/stake/types/stake_migration.go#L29

    "},{"location":"bc-fusion/developers/gov/","title":"New Governance","text":""},{"location":"bc-fusion/developers/gov/#governance","title":"Governance","text":"

    This guide provides an overview of the key operations of governance, including creating proposals, casting votes, and executing proposals. For the general introduction of governance, please refer to Governance Mechanism.

    "},{"location":"bc-fusion/developers/gov/#contract","title":"Contract","text":"

    The BSC governance facilitates decentralized decision-making within the BSC ecosystem, utilizing two primary smart contracts: GovToken for governance token management and Governor for proposal management and voting.

    "},{"location":"bc-fusion/developers/gov/#create-proposal","title":"Create Proposal","text":"

    To create a proposal, you need to call the propose function of Governor with the following parameters:

    function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory\n    description) public returns (uint256 proposalId)\n
    "},{"location":"bc-fusion/developers/gov/#cast-vote","title":"Cast Vote","text":"

    To cast a vote, you need to call the castVote function of Governor with the following parameters:

    function castVote(uint256 proposalId, uint8 support, string memory reason) public returns (uint256)\n
    "},{"location":"bc-fusion/developers/gov/#check-proposal-state","title":"Check Proposal State","text":"

    To get the state of a proposal, you need to call the state function of Governor with the following parameters:

    function state(uint256 proposalId) public view returns (ProposalState)\n
    "},{"location":"bc-fusion/developers/gov/#queue-proposal","title":"Queue Proposal","text":"

    To schedules the proposal for execution, you need to call the queue function of Governor with the following parameters:

    function queue(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)\npublic returns (uint256 proposalId)\n
    "},{"location":"bc-fusion/developers/gov/#execute-proposal","title":"Execute Proposal","text":"

    To apply the changes after the timelock delay, you need to call the execute function of Governor with the following parameters:

    function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)\npublic payable returns (uint256)\n
    "},{"location":"bc-fusion/developers/gov/#delegate-vote","title":"Delegate Vote","text":"

    To delegate voting power to someoneles, you need to call the delegateVote function of GovToken with the following parameters:

    function delegateVote(address delegator, address delegatee) external\n
    "},{"location":"bc-fusion/developers/gov/#contract-abi","title":"Contract ABI","text":"

    For the full interfaces of Governor, please refer to the ABI file.

    For the full interfaces of GovToken, please refer to the ABI file.

    "},{"location":"bc-fusion/developers/staking/","title":"New Staking","text":""},{"location":"bc-fusion/developers/staking/#staking","title":"Staking","text":"

    This guide provides an overview of the key operations of staking, including creating validators, editing validator information, and performing delegation operations. For the general introduction of staking, please refer to Staking Mechanism.

    "},{"location":"bc-fusion/developers/staking/#contract","title":"Contract","text":"

    The BSC staking mainly uses the smart contracts StakeHub for validator management and delegation management.

    "},{"location":"bc-fusion/developers/staking/#creating-a-validator","title":"Creating a Validator","text":"

    To create a validator, use the createValidator function with the following parameters:

      function createValidator(\n    address consensusAddress,\n    bytes calldata voteAddress,\n    bytes calldata blsProof,\n    Commission calldata commission,\n    Description calldata description\n) external payable\n

    Note: Creating a validator requires locking 1 BNB, and the transaction must be sent with a sufficient BNB amount to cover this lock amount plus any self-delegation, in total 2001BNB.

    "},{"location":"bc-fusion/developers/staking/#editing-validator-information","title":"Editing Validator Information","text":""},{"location":"bc-fusion/developers/staking/#edit-consensus-address","title":"Edit Consensus Address","text":"

    To change the consensus address of a validator, use the editConsensusAddress function with the following paramters:

    function editConsensusAddress(address newConsensusAddress) external\n
    "},{"location":"bc-fusion/developers/staking/#edit-commission-rate","title":"Edit Commission Rate","text":"

    To update the commission rate of a validator, use the editCommissionRate function with the following paramters:

    function editCommissionRate(uint64 newCommissionRate) external\n
    "},{"location":"bc-fusion/developers/staking/#edit-description","title":"Edit Description","text":"

    To update the description of a validator, use the editDescription function with the following parameters:

    function editDescription(Description memory newDescription) external\n
    "},{"location":"bc-fusion/developers/staking/#edit-vote-address","title":"Edit Vote Address","text":"

    To change the vote address of a validator, use the editVoteAddress function with the following parameters:

    function editVoteAddress(bytes calldata newVoteAddress, bytes calldata blsProof) external\n
    "},{"location":"bc-fusion/developers/staking/#delegation-operations","title":"Delegation Operations","text":""},{"location":"bc-fusion/developers/staking/#delegate","title":"Delegate","text":"

    To delegate BNB to a validator, call the delegate function with the following parameters:

    function delegate(address operatorAddress, bool delegateVotePower) external payable\n
    "},{"location":"bc-fusion/developers/staking/#undelegate","title":"Undelegate","text":"

    To undelegate BNB from a validator, use the undelegate function with the following parameters:

    function undelegate(address operatorAddress, uint256 shares) external\n
    "},{"location":"bc-fusion/developers/staking/#redelegate","title":"Redelegate","text":"

    To redelegate BNB from one validator to another, use the redelegate function with the following parameters:

    function redelegate(address srcValidator, address dstValidator, uint256 shares, bool delegateVotePower) external\n
    "},{"location":"bc-fusion/developers/staking/#claim","title":"Claim","text":"

    To claim undelegated BNB after the unbonding period, use the claim function for a single request or claimBatch for multiple requests:

    function claim(address operatorAddress, uint256 requestNumber) external\n
    function claimBatch(address[] calldata operatorAddresses, uint256[] calldata requestNumbers) external\n
    "},{"location":"bc-fusion/developers/staking/#faqs","title":"FAQs","text":""},{"location":"bc-fusion/developers/staking/#what-are-the-functionsinterfaces-of-each-validators-credit-contract","title":"What are the functions/interfaces of each validator\u2019s credit contract?","text":"

    For each validator, there is a credit contract which will be automatically deployed when it is created. Meanwhile, the conctract cannot be upgraded or changed by any validator operator.

    The credit contract is a BEP20 contract, and the ABI is the same as Stake Credit contract.

    It provides functions for querying delegations, including:

    "},{"location":"bc-fusion/developers/staking/#how-to-get-the-sharesbnb-amount-for-a-delegator","title":"How to get the shares/BNB amount for a delegator?","text":"

    For any specific validator, please call the balanceOf function of the validator\u2019s creat contract to get the delegator\u2019s shares. To get the BNB amount instead of shares, the function getPooledBNB can be used.

    To get the shares of all validators, please call the balanceOf function for each valiator and sum up the results. Please refer to the following to see how to get the information of all validators, and use a muticall contract to improve the efficiency.

    "},{"location":"bc-fusion/developers/staking/#how-to-calculte-the-bnb-amount-for-a-specific-amount-of-shares","title":"How to calculte the BNB amount for a specific amount of shares?","text":"

    The credit contract provides the getPooledBNBByShares function to calculate the BNB amount for some specific amount of shares.

    To do the vice visa, please use the getSharesByPooledBNB function to calculate the shares for some specific BNB amount.

    "},{"location":"bc-fusion/developers/staking/#how-to-calculate-the-aprapy-of-a-validator","title":"How to calculate the APR/APY of a validator?","text":"

    Please be noted that each validator will have its own APR/APY, and the staking system will auto compound the rewards.

    The reward is distributed to each validator\u2019s BNB pool at 00:00:00 UTC time every day. To calculate the APR/APY of a validator, the total pooled BNB amount and the corresponding reward amount for the same day are needed.

    The StakeHub contract provides the getValidatorTotalPooledBNBRecord(address,uint256)(uint256) and getValidatorRewardRecord(address,uint256)(uint256) for the purpose.

    The following codes show how to calculate the APY at a given day:

    // example code, do not use it in production\n\n// stakehub is the instance of StakeHub contract\nstakeHub, _ := contracts.NewStakeHub(ethcommon.HexToAddress(\"0x0000000000000000000000000000000000002002\"), client.GetEthClient())\n\n// get how many blocks are in a day\ninterval, _ := stakeHub.BREATHEBLOCKINTERVAL(nil)\n\n// get the block time of a given block\nheader, _ := p.client.GetBlockHeader(blockHeight)\n\n// calculate the index paramter to call the following functions\nindex := int64(header.Time) / interval.Int64()\n\n// get the total pooled BNB amount and the corresponding reward amount for the given validator and index\ntotalPooledBNB, _ := stakeHub.GetValidatorTotalPooledBNBRecord(nil, validatorOperatorAddress, index)\nreward, _ := stakeHub.GetValidatorRewardRecord(nil, validatorOperatorAddress, index)\n\n// calculate the APY\nrate, _ := big.NewFloat(0).Quo(big.NewFloat(0).SetInt(reward), big.NewFloat(0).SetInt(totalPooledBNB)).Float64()\napy := math.Pow(1+rate, 365) - 1.0\n
    "},{"location":"bc-fusion/developers/staking/#how-to-get-the-unbonding-delegations-of-a-delegator-and-hisher-unbonding-requests-which-can-be-claimed","title":"How to get the unbonding delegations of a delegator, and his/her unbonding requests which can be claimed?","text":"

    The credit contract provides the pendingUnbondRequest function to get the unbonding delegation count for a delegator. To review the details of a unbond request, please call the unbondRequest function with a index parameter to define which unbond request will be returned.

    To get the claimable unbonding requests, please call the claimableUnbondRequest function to get the count of claimable ones.

    To get the locked BNBs for unbonding requests, please use the lockedBNBs function. It has the parameter number to define the sum of first number unbonding requests\u2019 BNB locked in the delegator\u2019s unbond queue. Set the number to 0 to get all the locked BNBs.

    "},{"location":"bc-fusion/developers/staking/#how-to-get-the-reward-of-a-delegator","title":"How to get the reward of a delegator?","text":"

    The contracts does not save the initial delegation amount of a delegator. To get the accumulated reward, the following steps can be taken: 1) track the initial delegation amount in your system, 2) call the getPooledBNB of the credit contract of a validator, 3) do the math.

    "},{"location":"bc-fusion/developers/staking/#how-to-get-the-total-staking-address-of-a-validator","title":"How to get the total staking address of a validator?","text":"

    The contract does not provide a function to get the total staking address of a validator. It needs a offchain service to index Delegated, Redelegated, Undelegated events for the purpose. For example, you can consider building an indexer to crawl Delegated, Redelegated, Undelegated events on stakeHub contract first. Then sort the events according to your requirements.

    "},{"location":"bc-fusion/developers/staking/#how-to-get-all-validators-information","title":"How to get all validators\u2019 information?","text":"

    The StakeHub contract provides the getValidators function to get all validators\u2019 information, including the operator addresses and credit contract addresses.

    To get more information of a specific validator, please refer to the following functions:

    "},{"location":"bc-fusion/developers/staking/#contract-abi","title":"Contract ABI","text":"

    For the full interfaces of StakeHub, please refer to the ABI file.

    "},{"location":"bc-fusion/developers/system-contracts/","title":"Build-in System Contracts","text":""},{"location":"bc-fusion/developers/system-contracts/#build-in-system-contracts","title":"Build-in System Contracts","text":"

    GitHub Implementation link: https://github.com/bnb-chain/bsc-genesis-contract

    Contract Name Contract Address ABI File Stake Hub Contract 0x0000000000000000000000000000000000002002 stakehub Stake Credit Contract 0x0000000000000000000000000000000000002003 stakecredit Governor Contract 0x0000000000000000000000000000000000002004 bscgovernor Gov Token Contract 0x0000000000000000000000000000000000002005 govtoken Timelock Contract 0x0000000000000000000000000000000000002006 bsctimelock Token Recover Portal Contract 0x0000000000000000000000000000000000003000 tokenrecoverportal"},{"location":"bc-fusion/developers/system-contracts/#precompiled-contracts","title":"Precompiled Contracts","text":""},{"location":"bc-fusion/developers/system-contracts/#secp256k1-signature-recover","title":"Secp256k1 Signature Recover","text":"

    The precompiled contract is used to verify the signature of a message signed using the secp256k1 elliptic curve cryptography algorithm. It will also retrun the Tendermint address of the signer.

    "},{"location":"bc-fusion/developers/system-contracts/#verify-double-sign-evidence","title":"Verify Double Sign Evidence","text":"

    The precompiled contract is used to verify the submitted double sign evidence, which includes the two block headers signed by the same validator at different times.

    "},{"location":"bc-fusion/developers/system-contracts/#build-in-system-contracts_1","title":"Build-in System Contracts","text":""},{"location":"bc-fusion/developers/system-contracts/#stake-hub-contract","title":"Stake Hub Contract","text":"

    The Stake Hub contract is a contract that manages the staking process, including delegation, undelegation, redelegation, and claiming rewards.

    "},{"location":"bc-fusion/developers/system-contracts/#stake-credit-contract","title":"Stake Credit Contract","text":"

    The Stake Credit contract is a template proxy contract. When a validator is created, a new stake credit contract is deployed, to manage staking credit and facilitate the exchange between credit and BNB.

    "},{"location":"bc-fusion/developers/system-contracts/#governor-contract","title":"Governor Contract","text":"

    The Governor contract is a contract that manages the BNB Smart Chain governance process. It allows users to propose and vote on changes to the protocol.

    "},{"location":"bc-fusion/developers/system-contracts/#gov-token-contract","title":"Gov Token Contract","text":"

    The Gov Token contract is a contract that manages the governance token, i.e., govBNB.

    "},{"location":"bc-fusion/developers/system-contracts/#timelock-contract","title":"Timelock Contract","text":"

    The Timelock contract is a contract that allows executing a time lock on some specific operations (e.g., token recovery). After the timelock period, the locked tokens can be claimed or released.

    "},{"location":"bc-fusion/developers/system-contracts/#token-recover-portal-contract","title":"Token Recover Portal Contract","text":"

    The Token Recover Portal contract is a contract that allows users to recover their BEP2/BEP8 tokens, which must have been bound to BEP20 tokens, after the shutdown of the cross-chaind transfer between BNB Smart Chain and BNB Beacon Chain.

    "},{"location":"bc-fusion/owners/bind/","title":"Bind Your Tokens","text":""},{"location":"bc-fusion/owners/bind/#token-bind","title":"Token Bind","text":"

    Token binding was introduced to faciliate that one token can circulate in both BC and BSC with confirmed total supply.

    NOTE: The BC Fusion program is scheduled for implementation in April 2024. Please ensure careful planning for the asset migration and keep the fund safe.

    Please check the tutorial Confirm if the Assets Support Cross-chain Transfers to verify if the token allows cross-chain transfers. If the answer is positive, congratulations! You don\u2019t need to do anything. Otherwise, it is highly recommended to follow the Token Bind Tool to deploy a BEP20 token on BSC and enable cross-chain functionality.

    Due to the time limitation, the Token Issuer should take actions as soon as possbile. It is recommended that the Token Issuer use multiple channels to promptly notify asset holders to migrate as soon as possible.

    Note: BEP2/BEP8 assets that do not support cross-chain functionality will be permanently lost after BC Fusion. Users will be unable to recover these assets forever.

    "},{"location":"bc-fusion/owners/liquidity-check/","title":"Cross Chain Liquidity Check and Repair","text":""},{"location":"bc-fusion/owners/liquidity-check/#cross-chain-liquidity-check-and-repair","title":"Cross-Chain Liquidity Check and Repair","text":"

    After token binding, tokens can be seamlessly transferred between BC and BSC. However, some improper operations may lead to eventual cross-chain transfer failures. For example, performing a mint operation on one chain but not on the other can result in different supplies on the two chains, making it impossible to transfer all assets from the chain with the larger total supply to the other chain. This doc will introduce the token circulation model of BNB Chain and how to repair cross-chain liquidity issues. We urge all token issuers to complete liquidity checks and repairs before BC Fusion, although this article remains valid after BC Fusion.

    "},{"location":"bc-fusion/owners/liquidity-check/#circulation-model","title":"Circulation Model","text":"

    The architecture of cross-chain communication is as in the above diagram. The cross-chain transfer is the key communication between the two blockchains. Essentially the logic is:

    1. The transfer-out blockchain will lock the amount from source owner addresses into a system controlled address/contracts
    2. The transfer-in blockchain will unlock the amount from the system controlled address/contracts and send it to target addresses.

    The system controlled vault on BNB Beacon Chain is bnb1v8vkkymvhe2sf7gd2092ujc6hweta38xadu2pj which is generated by code, and the vault on BNB Smart Chain is a system smart contract called Token Hub. The funds on these two addresses are treated as locked which are not part of the circulating supply.

    "},{"location":"bc-fusion/owners/liquidity-check/#liquidity-check-and-repair","title":"Liquidity Check and Repair","text":"

    One of the objectives of BC Fusion is to transfer all tokens from the Beacon Chain to BSC. Therefore, we must ensure that there is sufficient liquidity on BSC, meaning the total amount of tokens locked in BSC\u2019s Tokenhub is greater than the circulating supply on the Beacon Chain.

    Let\u2019s use take DAI token as an example:

    1. Visit the basic information page of DAI on the Beacon Chain explorer to obtain the circulating supply on the Beacon Chain (Csupply) and the contract address on BSC.
    2. Visit the BSC explorer to check the locked amount/liquidity of this token. The URL is https://bscscan.com/token/${BSC_contract_address}?a=0x0000000000000000000000000000000000001004. Replace ${BSC contract address} with the BSC contract address obtained in step 1. And you will see the balance as below:

    Therefore, Tokenhub on BSC still lacks 1,999,973.28 - 1.755760127949865335 = 1,999,971.5242398721 DAI. To avoid issues caused by precision loss, we recommend adding slightly more liquidity than the calculated value. In this case, it would be 1,999,972 DAI. If you find that the amount of locked tokens on BSC is greater than the circulating supply (Csupply) on the Beacon Chain, it means there is sufficient liquidity, and no further action is needed.

    If there is a liquidity shortage, the issuer of the token should transfer the missing liquidity to Tokenhub, for example, 1,999,972 DAI for the DAI token mentioned above. The source of these tokens is up to the issuer to determine: they could be minted or collected from various accounts.

    "},{"location":"bc-fusion/post-fusion/faq/","title":"FAQ","text":""},{"location":"bc-fusion/post-fusion/faq/#faq","title":"FAQ","text":""},{"location":"bc-fusion/post-fusion/faq/#1-what-will-happen-during-and-after-the-final-sunset-hardfork","title":"1. What will happen during and after the final sunset hardfork?","text":"

    Before executing Final Sunset, users still have the opportunity to transfer funds across chains. However, after Final Sunset, cross-chain communication between the Beacon Chain and BSC will be completely stopped.

    After Sunset Fork (i.e., post fusion), the validators in the Beacon Chain community will gradually shut down, and the entire chain will no longer accept new transactions or propose new blocks.

    Some of the funds will be permanently locked:

    All these funds are not recoverable after the Final Sunset Fork.

    After BC shutdown, the core dev team will dump the ledger of Beacon Chain and generate a merkle tree. A governance proposal will be submitted to set the merkel root and approver account of the token migration contract. A dapp (token recovery dApp) will be provided for token migration from Beacon Chain to BSC. All the blockchain data of Beacon Chain will be uploaded to Greenfield, Filecoin and Arweave for archive.

    "},{"location":"bc-fusion/post-fusion/faq/#2what-users-should-do-to-manage-their-bep2bep8-assets-before-and-after-the-fusion","title":"2.What users should do to manage their BEP2/BEP8 assets before and after the fusion?","text":"

    Before the final sunset hardfork:

    After the final sunset hadfork (i.e., post fusion):

    Important: to use the token recovery dApp, the private key/mnemonic for your BC account will be used to prove that you are the owner of the assets. Please take care of your key/mnemonic.

    "},{"location":"bc-fusion/post-fusion/faq/#3-how-do-users-access-the-balance-snapshot-post-fusion","title":"3. How do users access the balance snapshot post fusion?","text":""},{"location":"bc-fusion/post-fusion/faq/#4-can-i-still-acccess-the-bc-releated-services-or-products-after-the-fusion","title":"4. Can I still acccess the BC releated services or products after the fusion?","text":"

    Most of the BC related services and products will be shut down after the final sunset hardfork, inluding and not limited to:

    Be noted: No snapshot will be provided for any of the BC related services and products.

    The Beacon Chain Explorer will keep running for users to query the blockchain data, however, the explorer for BC testnet will be shut down if there is no query traffic for a long time.

    "},{"location":"bc-fusion/post-fusion/merkle-tree-verify/","title":"Merkle Proof Verification","text":""},{"location":"bc-fusion/post-fusion/merkle-tree-verify/#verify-merkle-tree-proofs","title":"Verify Merkle Tree Proofs","text":"

    The BEP299 describes how to recover the bound BEP2/BEP8 on the BSC afer the fusion. One of the most important steps is to generate and verify the Beacon Chain merkle tree proofs. If a wrong merkle tree root is generated, the bound BEP2/BEP8 cannot be recovered and there will a huge financial loss.

    Therefore, the communities are encouraged to use the following tools to verify the proofs and report any issues.

    To do the verification, please follow the detailed steps in the following links:

    "},{"location":"bc-fusion/post-fusion/token-recovery/","title":"Token Recovery","text":""},{"location":"bc-fusion/post-fusion/token-recovery/#token-recovery-dapp","title":"Token Recovery dApp","text":"

    To facilitate the token migration after the Beacon Chain shutdown, the BEP299 is proposed to recover the BEP2/BEP8 assets on the Beacon Chain to the BSC chain. This document will guide you through the process of token recovery.

    Be noted:

    URL:

    "},{"location":"bc-fusion/post-fusion/token-recovery/#steps","title":"Steps","text":""},{"location":"bc-fusion/post-fusion/token-recovery/#step-1-connect-to-your-bc-wallet","title":"Step 1: Connect to your BC wallet.","text":"

    When opening the token recovery dApp, you will be prompted to connect to your wallet.

    BNB Chain Wallet and Trust Wallet will be supported (Trust wallet support will come soon).

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-2-select-the-bep2bep8-assets-to-be-recovered","title":"Step 2: Select the BEP2/BEP8 assets to be recovered.","text":"

    Click the \u201cRecover Now\u201d button to start the recovery process.

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-3-input-the-receiver-address","title":"Step 3: Input the receiver address.","text":"

    The receiver address on BSC is the address where the BEP2/BEP8 assets will be recovered to. The token recovery dApp will try to get the BSC address from your wallet automatically.

    If the address is not populated or you want to use a different address, you can also input the address you want to use.

    Be noted:

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-4-confirm-the-receiver-address-and-signing","title":"Step 4: Confirm the receiver address and signing.","text":"

    By confirming the token recovery request, you will be promoted to sign a message via your wallet.

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-5-send-the-token-recovery-transaction-to-bsc","title":"Step 5: Send the token recovery transaction to BSC.","text":"

    You will be asked to switch to the BSC network in your wallet.

    The connected address should be the receiver address inputted in the previous step. If it is not, the token recovery dApp will detect it and ask you to switch to the correct account in your wallet.

    Then click the \u201cConfirm\u201d button to send the token recovery transaction to BSC.

    You will be prompted to sign and confirm the transaction, which will be sent to the BSC.

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-6-wait-for-the-recovery","title":"Step 6: Wait for the recovery.","text":"

    After the transaction is sent, the token recovery dApp will populate a window to indicate that the token recovery request is sent successfully.

    Finally, you need to wait for 7 days for the BEP2/BEP8 assets to be recovered on BSC and received in your wallet.

    "},{"location":"bc-fusion/users/assets/","title":"Manage Your Assets","text":""},{"location":"bc-fusion/users/assets/#asset-management","title":"Asset Management","text":"

    The BNB Chain community recently introduced BEP333: BNB Chain Fusion. This BEP aims to retire the BNB Beacon Chain from the BNB Chain ecosystem. The goal is to enhance the development efficiency, security, and asset utilization efficiency of BSC. It also aims to reduce the maintenance costs of legacy services. This tutorial aims to help digital asset issuers and holders on the BNB Beacon Chain transfer the value of their assets, including BEP2/BEP8 tokens, before and after BC Fusion. By following this guide, users can avoid any potential losses of their valuable digital assets.

    NOTE: The BC Fusion program is scheduled for implementation in April 2024. Please ensure careful planning for the asset migration and keep the fund safe.

    "},{"location":"bc-fusion/users/assets/#before-bc-fusion","title":"Before BC Fusion","text":"

    Most valuable BEP2/BEP8 tokens such as BNB, BTC, and BUSD can freely move between the Beacon Chain and BSC networks. Users are strongly advised to transfer their assets to the BSC network to ensure a seamless and lossless transition, maintaining a 1:1 ratio. Of course, there are alternative channels available for asset transfers, such as utilizing centralized exchanges or decentralized cross-chain exchanges like Binance.com and Thorswap. However, these options are beyond the scope of this tutorial.

    Step1: Confirm if the Assets Support Cross-chain Transfers

    Open the Beacon Chain blockchain explorer, go to the BEP2 Asset page or BEP8 Asset page, and search for the token name to query it. Using BTC as an example, it is linked to a BSC Contract address, allowing for cross-chain transfers.

    In contrast to GTEX-71B, which lacks a BSC Contract address and thus does not support cross-chain transfers.

    If a user needs to transfer assets that don\u2019t support cross-chain transfers, it\u2019s strongly recommended to contact the token owner/issuer as soon as possible. Ask the token issuer to refer to the token bind tutorial for issuing BEP20 tokens on BSC and enabling cross-chain transfers. If the token issuer does not enable cross-chain transfer for the token before the sunset of BNB Beacon Chain, the funds will be lost forever and can not be recovered.

    Step2: Simply Transfer the Assets to the BSC Network

    BNB Chain Wallet and Trust Wallet mobile are suggested for this case. Taking BNB Chain Wallet as an example, once users import the accounts that have the tokens, they need to switch the network to \u201cBNB Beacon Chain Network\u201d:

    Then, select the asset to transfer, enter the BSC account and the token amount.

    The BSC wallet will receive the token after approximately one minute.

    For Trust Wallet mobile multi-chain wallet users, they can transfer their assets in the following way.

    Firstly, you need to open the Swap tab, choose From network as BNB Beacon Chain and To network as BNB Smart Chain, then find the asset you want to transfer and input the transfer amount. After you click the Continue button, it will redirect you to the approval page as below.

    Finally, the related asset will be transferred to BSC after you confirm the transaction.

    "},{"location":"bc-fusion/users/assets/#after-bc-fusion","title":"After BC Fusion","text":"

    Following the retirement of Beacon Chain, it is believed that some users have not yet transferred their assets to the BSC network. BNB Chain is still providing relief measures for these users: BEP299-Token Migration after BC Fusion.

    Although this solution has its limitations, it is important to note the following key points:

    1. It is only applicable to assets that have enabled cross-chain features. The BEP2/BEP8 assets will be permanently lost if not the case.

    2. Users are still responsible for securely storing their private keys on the Beacon Chain and using them for signing as proof.

    3. The process of recovering assets will take up to 7 days to complete.

    4. This solution is operated through the command line and does not provide any UI.

    Considering these limitations, it is highly recommended that users complete the token transfer before BC fusion as much as possible.

    The detailed guide for this solution will be published after the BC Fusion. Stay tuned for the update.

    "},{"location":"bc-fusion/users/bep153-stake-migration/","title":"BEP153 and LSD Stake Migration","text":""},{"location":"bc-fusion/users/bep153-stake-migration/#stake-migration-for-bep153","title":"Stake Migration For BEP153","text":"

    The BEP-153 has been introduced as a native staking protocol onto BNB Smart Chain before BNB Chain fusion. With this BEP, individual or institution delegators can stake BNB to specified validators and get staking rewards on the BSC side directly.

    However, underlying the protocol users\u2019 BNB are crosschain transferred to the Beacon Chain and then staked there. With the BNB Chain fusion, the delegators of BEP-153 needs to migrate their stakes to the new staking system.

    For BEP-153 stakes, the delegators need to undelegate, wait for the unbounding period (7 days), and then get their BNB back to stake on the new staking system.

    This document will guide you through the process of stake migration for BEP-153 delegators, including Liquid Staking Derivatives (LSD) protocol\u2019s users.

    "},{"location":"bc-fusion/users/bep153-stake-migration/#for-individual-delegators","title":"For Individual Delegators","text":"
    1. Open the Staking contract on BSCScan

    2. You can find your delegation information on the \u201cTransactions\u201d tab, or you can query the contract as the following:

    3. Undelegate your delegations by calling the undelegate function

    4. Afther the unbounding period (7 days), call the claimUndelegated function to get your BNB back

    5. Then you can delegate your BNB to the new staking system by following the new staking guide

    "},{"location":"bc-fusion/users/bep153-stake-migration/#for-lsd-protocol-delegators","title":"For LSD Protocol Delegators","text":"
    1. Go to your LSD protocol dApps and undelegate your delegations

    2. Wait for the unbounding period (7 days)

    3. Then you can delegate your BNB to the new staking system by following the new staking guide

    "},{"location":"bc-fusion/users/bep153-stake-migration/#for-lsd-protocol-projects","title":"For LSD Protocol Projects","text":"

    For LSD protocol projects, you MUST finish your undelegations before the Second Sunset Fork of Beacon Chain. In the Second Sunset Fork, all the delegations will automatically be returned to the delegator addressess. If your delegation address is not an EOA address, you will lose the control of your stakes and the fund will be lost.

    "},{"location":"bc-fusion/users/gov/","title":"Participate in Governance","text":""},{"location":"bc-fusion/users/gov/#governance-with-tally","title":"Governance with Tally","text":"

    This document provides a guide on how to participate in governance on the BNB Smart Chain (BSC) using Tally. It covers the process of delegating voting power, creating proposals, voting on proposals, and executing proposals.

    BNB Chain DAOs are created on Tally both for the mainnet and testnet.

    "},{"location":"bc-fusion/users/gov/#parameters","title":"Parameters","text":"

    There are several parameters which will affect the governance process on the BSC. Especially, the governance process on the BSC only enabled after enough voting power is migrated from the Beacon Chain to the BSC (i.e., the startGovThreshold parameter).

    Parameter Description Mainnet Value Testnet Value votingDelay a fixed duration after which users can vote to a proposal 0 hour 0 hour votingPeriod the voting period before tally 7 days 1 day proposalThreshold a fixed amount of gov BNB needed for a proposal 200 govBNB 100 govBNB quorumNumberRator the percentage of the total voting power required to produce a final vote result 10% 10% startGovThreshold the total supply of gov token to enable the gov function 10M BNB 10M BNB minPeriodAfterTheQuorum the time to add for voting when a proposal reaches quorum 1 day 1 hour timerlockDelay the timer locker duration to execute a proposal 1 day 6 hours"},{"location":"bc-fusion/users/gov/#governance-process-guide","title":"Governance Process Guide","text":"

    You need to connect to your Web3 wallet (e.g., TrustWallet, BEW, Metamask) for the following operations.

    "},{"location":"bc-fusion/users/gov/#delegate-voting-power","title":"Delegate Voting Power","text":"

    After you have delegated your BNB to a BSC validator, you can start participating in the BSC governance. To participate in BSC governance, you first need to delegate your voting power to someone or yourself if you wish to vote directly.

    You can click the My voting power button on the top right corner of the screen to delegate your voting power.

    You can delegate your voting power to yourself if you want to vote/create proposals directly, or to others if you want him/her to vote/create proposals on your behalf.

    If you delegate the voting power to yourself, you will see the current number of your voting power to participate in the governance.

    "},{"location":"bc-fusion/users/gov/#create-proposals","title":"Create Proposals","text":"

    If you have sufficient voting power (i.e., greater than the proposalThreshold), you can create proposals on the BSC network. Be noted that a user can only has one proposal in active/pending state at a time to prevent spamming.

    To create a proposal, click on the \u201cCreate new proposal\u201d button on the top right corner of the screen.

    After you have created a proposal, you can add a title, description, and a list of actions for the proposal.

    A text proposal only requires a title and a description, and it will not be executed by the network for there is no action.

    To add an action, click on the \u201cAdd action\u201d button, and fill in the details of the action.

    After you input all the details, click on the \u201cPublish\u201d will publish your proposal.

    You can also cancel a proposal by clicking on the \u201cCancel proposal\u201d button.

    "},{"location":"bc-fusion/users/gov/#vote-on-proposals","title":"Vote on Proposals","text":"

    Once a proposal is live (i.e., after the votingDelay and before the votingPeriod), you can cast your vote to support or oppose the proposal. To vote on a proposal, click on the \u201cVote on chain\u201d button.

    You can cast For, or Against, or Abstain votes to the proposal.

    "},{"location":"bc-fusion/users/gov/#execute-proposals","title":"Execute Proposals","text":"

    If a proposal reaches the quorum (i.e., reaches the quorumNumberRator of the total voting power) and it passes (i.e., more than 50% of the voted voting power supports the proposal), it can be executed by the network.

    To execute a proposal, fistly the proposal needs to be queued by clicking the Queue button.

    After the proposal is queued and exceeds the timelock duration (i.e, the timerlockDelay duration), it can be executed by anyone by clicking the Execute button.

    "},{"location":"bc-fusion/users/gov/#more-references","title":"More References","text":""},{"location":"bc-fusion/users/new-stake/","title":"Manage Your New Delegations","text":""},{"location":"bc-fusion/users/new-stake/#managing-new-stakes-with-bnb-staking-dapp","title":"Managing New Stakes with BNB Staking dApp","text":"

    Leverage the BNB staking dApp for streamlined management of your stakes. This guide provides a step-by-step walkthrough for using the dApp on both testnet and mainnet.

    "},{"location":"bc-fusion/users/new-stake/#connecting-your-wallet","title":"Connecting Your Wallet","text":"

    To interact with the dApp, first connect your web3 wallet. Currently, TrustWallet (mainnet only) and MetaMask are supported, along with any wallets compatible with WalletConnect.

    "},{"location":"bc-fusion/users/new-stake/#delegate-stakes","title":"Delegate Stakes","text":"
    1. Select a validator to delegate your stakes to. Detailed information about each validator is available on their respective pages.
    2. Click the Delegate button to initiate a new delegation.

    3. Enter the amount of BNB you wish to delegate.

    4. After confirming the delegation, your connected wallet will prompt you to sign the transaction. Successful transactions will be visible in the My Staking page, complete with transaction hash.

    "},{"location":"bc-fusion/users/new-stake/#redelegate-stakes","title":"Redelegate Stakes","text":"

    On the My Staking page, you can manage your existing delegations.

    Note: A redelegation fee of 0.002% applies to discourage frequent switching between validators.

    1. Click Redelegate to shift your stake to a different validator.

    2. In the ensuing popup, select your new validator and specify the amount to redelegate. You can opt to move the entire amount or just a portion.

    "},{"location":"bc-fusion/users/new-stake/#undelegate-stakes","title":"Undelegate Stakes","text":"

    To undelegate:

    1. Click the Undelegate button next to the relevant delegation.

    2. You can choose to undelegate the entire amount or a portion. Note that undelegated stakes are subject to a 7-day unbonding period before they are returned to your account.

    "},{"location":"bc-fusion/users/new-stake/#claim-stakes","title":"Claim Stakes","text":"

    After the unbonding period, you can claim your stakes by clicking the Claim button.

    "},{"location":"bc-fusion/users/new-stake/#faqs","title":"FAQs","text":""},{"location":"bc-fusion/users/new-stake/#which-wallet-can-be-used-to-delegate-to-the-new-validators","title":"Which wallet can be used to delegate to the new validators?","text":"

    Currently, MetaMask and TrustWallet (mainnet only) and are supported, along with any wallets compatible with WalletConnect.

    "},{"location":"bc-fusion/users/new-stake/#as-a-validator-operator-should-i-keep-both-the-original-validator-after-i-create-a-new-validator-on-the-bsc","title":"As a validator operator, should I keep both the original validator after I create a new validator on the BSC?","text":"

    It is recommended to keep both validators for a period of time to allow for smooth migration. It would be better to ask your delegators to migrate their stakes to the new validator. After your new validator is elected as cabinet or candidate, you can safely retire the old validator.

    "},{"location":"bc-fusion/users/new-stake/#how-should-i-migrate-my-delegations-if-my-bnb-was-delegated-through-the-bsc-smart-contract","title":"How should I migrate my delegations if my BNB was delegated through the BSC smart contract?","text":"

    Please refer to the stake migration guide for BEP153 delegations.

    "},{"location":"bc-fusion/users/stake-migration/","title":"Manage Your Old Delegations","text":""},{"location":"bc-fusion/users/stake-migration/#stake-migration","title":"Stake Migration","text":"

    The BNB Chain community has introduced BEP333: BNB Chain Fusion, a significant update that retires the BNB Beacon Chain from the ecosystem. This transition introduces native staking on the BNB Smart Chain, following the Feynman Hardfork. Stakeholders now have the opportunity to migrate their existing delegations to the new native staking system through two primary methods:

    Be noted, for delegations which are created in BEP-153 format, please refer to this document for the migration process.

    "},{"location":"bc-fusion/users/stake-migration/#cross-chain-redelegation","title":"Cross Chain Redelegation","text":"

    Cross chain redelegation allow users to migrate their delegations to BSC as delegations to native BSC validators, facilitaling users for easier migration compared to the second option. Therefore this is the recommended way for stake migration.

    "},{"location":"bc-fusion/users/stake-migration/#steps","title":"Steps","text":""},{"location":"bc-fusion/users/stake-migration/#step-1-find-your-delegations","title":"Step 1: Find your delegations","text":"

    Go to the staking website and connect to your web3 wallet.

    Mainnet Staking Website: https://www.bnbchain.org/en/staking

    Testnet Staking Website: https://testnet-staking.bnbchain.org/en/staking

    For testnet, you can BNB Chain Wallet to connect.

    For mainnet, you can use BEW or TrustWallet to connect.

    Open My Staking page, Then you can find you existing delegations as the following.

    "},{"location":"bc-fusion/users/stake-migration/#step-2-choose-the-native-bsc-validators-to-migrate-to","title":"Step 2: Choose the native BSC validators to migrate to.","text":"

    Choose one delegation and click Migrate to BSC button. The following window will be poped up for choosing which BSC valiadtor you want to migrate to.

    The window mainly contains the following fields:

    "},{"location":"bc-fusion/users/stake-migration/#setp-3-sign-the-migrate-transaction","title":"Setp 3: Sign the migrate transaction.","text":"

    Finally, you can sign the transaction and migration will be started.

    If the migration fails, the fund will be returned to your Beacon Chain, and you can check it in your web3 wallet.

    If the migration goes well, you will find the delegation in the new staking dApp. For how find your delegations, please refer to this document for more information.

    "},{"location":"bc-fusion/users/stake-migration/#undelegation-cross-chain-transfer-new-delegation","title":"Undelegation, Cross Chain Transfer, New Delegation","text":"

    The second option needs the delegator to 1) do undelegation on the Beacon Chain, wait the unboinding period, 2) cross chain transfer BNB to the BSC, and 3) stake in the new staking dApp. It needs more time and transaction fee, therefore it is not recommended.

    "},{"location":"bc-fusion/users/stake-migration/#steps_1","title":"Steps","text":""},{"location":"bc-fusion/users/stake-migration/#step-1-find-your-delegations_1","title":"Step 1: Find your delegations","text":"

    You can find your delegations as the steps in the option 1.

    "},{"location":"bc-fusion/users/stake-migration/#step-2-undelegate","title":"Step 2: Undelegate","text":"

    Then you can undelegate your delegations by click Undelegate button and send the transaction to the Beacon Chain.

    After the unbonding period (7 days in mainnet), the stake be returned to your Beacon Chain account.

    "},{"location":"bc-fusion/users/stake-migration/#step-3-cross-chain-transfer","title":"Step 3: Cross chain transfer","text":"

    You can use BNB Chain Wallet (BEW) or TrustWallet to cross chain transfer your BNB from the Beacon Chain to the BSC.

    For BEW, you need to switch the network to \u201cBNB Beacon Chain Network\u201d/\u201dBNB Beacon Chain Testnet Network\u201d:

    Then, select the asset to transfer, enter the BSC account and the token amount.

    The BSC wallet will receive the token after approximately one minute.

    For TrustWallet mobile multi-chain users, you need to open the Swap tab, and choose From network as BNB Beacon Chain and To network as BNB Smart Chain for mainnet asset transfer.

    Then find the asset you want to transfer and input the transfer amount.

    After you click the Continue button, it will redirect you to the approval page as below.

    Finally, the related asset will be transferred to BSC after you confirm the transaction.

    "},{"location":"bc-fusion/users/stake-migration/#step-4-delegate-to-new-validators","title":"Step 4: Delegate to new validators","text":"

    Finnally, you can delegate to the new BSC valdiators using the new staking dApp. You can refer to this document for the detailed steps.

    "},{"location":"bc-fusion/users/swaps/","title":"Manage Your Atomic Swaps","text":""},{"location":"bc-fusion/users/swaps/#atomic-swap-management","title":"Atomic Swap Management","text":"

    HTLC based atomic swaps are introduced in BEP3, to facilitate payment and asset exchanges between different blockchains. For BC fusion, in the first sunset hardfork, the creation and deposit of atomic swaps will be disabled, project owners (e.g., cross-chain exchanges, bridges) and users should be aware of this and take proactive steps.

    "},{"location":"bc-fusion/users/swaps/#query-atomic-swaps","title":"Query Atomic Swaps","text":"

    The atomic swap api is provided to query existing atomic swaps. Usually, user can provide a from address to query the related atomic swaps, for example:

    https://dex.bnbchain.org/api/v1/atomic-swaps?fromAddress=bnb1xz3xqf4p2ygrw9lhp5g5df4ep4nd20vsywnmpr

    The response will contain a lot of useful information, such as id of the swap, the asset of the swap, and other information.

    "},{"location":"bc-fusion/users/swaps/#handle-atomic-swaps","title":"Handle Atomic Swaps","text":""},{"location":"bc-fusion/users/swaps/#before-bc-fusion","title":"Before BC Fusion","text":"

    A user can proactively refund his/her atomic swaps by sending HTLC Refund transactions to Beacon Chain. The command to send such transaction is looks like this:

    ./bnbcli token refund --swap-id <swapID> --from <from-key> --chain-id Binance-Chain-Tigris --trust-node --node http://dataseed1.bnbchain.org:80\n

    If no proactive refunds are submitted, in the second sunset hardfork, all existing atomic swaps will be automatically refunded to the creators\u2019 accounts on Beacon Chain. The refund will proceed in many Beacon Chain blocks, depending on how many atomic swaps still exist on the blockchain. After refund, users should be able to find the assets in their accounts. Then users can handle the assets as other BEP2/BEP8 tokens. For how to cross transfer them to BNB Smart Chain, please refer to this tutorial.

    "},{"location":"bc-fusion/users/swaps/#after-bc-fusion","title":"After BC Fusion","text":"

    If the refunded assets are not transferred to BSC before the final sunset fork, users need to use the token-recover tool to get their binded BEP2/BEP8 assets. For more information, please refer to this tutorial.

    "},{"location":"bc-fusion/users/swaps/#for-atomic-swap-project-owers","title":"For Atomic Swap Project Owers","text":"

    Because in the first sunset hardfork, the creation and deposit of atomic swaps will be disabled, so project owners need to disable related functions in their projects IN ADVANCE and notify their uses to take proactive actions to refund their tokens.

    "},{"location":"bc-fusion/users/timelocks/","title":"Manage Your TimeLocks","text":""},{"location":"bc-fusion/users/timelocks/#timelock-management","title":"TimeLock Management","text":"

    A timelock is a feature that allows users to lock their assets for a certain period of time, which is introduced in (https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP9.md). For BC fusion, in the second sunset hardfork, all timelocks will be refunded to users\u2019 accounts. Users should proactively actionsj to transfer these assets to BSC after receiving the refunds.

    "},{"location":"bc-fusion/users/timelocks/#query-timelocks","title":"Query TimeLocks","text":"

    The time lock api is provided to query existing timelocks. Usually, user can provide a from address to query the related timelocks, for example:

    https://dex.bnbchain.org/api/v1/timelocks/bnb1rmet5j5pwc3xvhd82rwdjkvewzgmreh6we72sf

    The response will contain a lot of useful information, such as id of the timelock, the asset of the timelock, and the unlock time.

    "},{"location":"bc-fusion/users/timelocks/#handle-timelocks","title":"Handle TimeLocks","text":"

    Once the timelock is created, the owners cannot access their assets until the unlock time has passed. During the second sunset hardfork, all existing timelocks will be automatically refunded to the creators\u2019 accounts on Beacon Chain. The refund will proceed in many Beacon Chain blocks, depending on how many timelocks still exist on the blockchain. After refund, users should be able to find the assets in their accounts. Then users can handle the assets as other BEP2/BEP8 tokens. For how to cross transfer them to BNB Smart Chain, please refer to this tutorial.

    "},{"location":"bc-fusion/validators/creation/","title":"Create New Validators","text":""},{"location":"bc-fusion/validators/creation/#validator-creation-guide","title":"Validator Creation Guide","text":"

    This guide outlines the process for creating a new validator on the BNB Smart Chain (BSC). The BNB staking dApp is the official tool for creating and managing validators on the BSC.

    "},{"location":"bc-fusion/validators/creation/#terminology","title":"Terminology","text":""},{"location":"bc-fusion/validators/creation/#steps","title":"Steps","text":""},{"location":"bc-fusion/validators/creation/#1-connecting-to-the-dapp","title":"1. Connecting to the dApp","text":"

    Please connect to the staking dApp using your Operator Address. Trust Wallet, MetaMask, and WalletConnect options are available for the step. Make sure that the account has more than 2001 BNB before moving on to the next step.

    "},{"location":"bc-fusion/validators/creation/#2-filling-out-the-form","title":"2. Filling out the form","text":"

    Navigate to the dApp and select the Become a Validator button in the right middle of the page to initiate the creation process.

    The following information is required to create a validator.

    "},{"location":"bc-fusion/validators/creation/#basic-information","title":"Basic Information","text":"

    You\u2019ll need to provide the following details on the Create Validator page:

    To enhance your validator\u2019s visibility, consider uploading additional information to the BSC validator directory. Your avatar, once uploaded, will be displayed in the staking dApp.

    "},{"location":"bc-fusion/validators/creation/#addresses","title":"Addresses","text":"

    The following addresses are required:

    "},{"location":"bc-fusion/validators/creation/#generate-consensus-address","title":"Generate Consensus Address","text":"

    Download the BSC geth binary from the official release page.

    Note: Make sure you are downloading the correct binary based on your machine\u2019s platform, e.g., if you are using MacOS, you should download the geth_mac file. In the following, we will refer the binary as geth for simplicity.

    To create a new account for mining, please use the following command and set a password for the account.

    geth account new --datadir ${DATA_DIR}\n

    This command will return the public address (i.e. consensus address) and the path to your private key. Please backup the key file!

    An example consensus address is 0x4b3FFeDb3470D441448BF18310cAd868Cf0F44B5.

    If you already have an account for mining, you can use the seed phrase to recover the account.

    geth account import --datadir ${DATA_DIR}\n

    If you have created a validator on the Beacon Chain, please use a different one for the consensus address.

    "},{"location":"bc-fusion/validators/creation/#generate-vote-address-and-bls-proof","title":"Generate Vote Address and BLS Proof","text":"

    To create a new BLS account please use the following command.

     geth bls account new --datadir ${DATA_DIR}\n

    If you already have a voting key, create a bls wallet and use the keyfile to recover it, using the following command.

     geth bls account import ${KEY_FILE} --datadir ${DATA_DIR}\n

    Then you can get your vote address by running the following command.

    geth bls account list --datadir ${DATA_DIR}\n

    An example address is b5fe571aa1b39e33c2735a184885f737a59ba689177f297cba67da94bea5c23dc71fd4deefe2c0d2d21851eb11081f69.

    Then you can get your bls proof by running the following command.

    geth bls account generate-proof --chain-id ${BSC_CHAIN_ID} ${OPEATOR_ADDRESS} ${VOTE_ADDRESS}\n

    An example proof is 0xaf762123d031984f5a7ae5d46b98208ca31293919570f51ae2f0a03069c5e8d6d47b775faba94d88dbbe591c51c537d718a743b9069e63b698ba1ae15d9f6bf7018684b0a860a46c812716117a59c364e841596c3f0a484ae40a1178130b76a5.

    "},{"location":"bc-fusion/validators/creation/#create-indentity","title":"Create indentity","text":"

    Identity is used for assocaiting the new validator to the old validator created on the Beacon Chain, to facilitate delegators moving their stakes to the same validator operator when migrations. If you never create a validator in this page, you can leave it empty.

    Please download BC client binary from the official release page.

    Note: Make sure you are downloading the correct binary based on your machine\u2019s platform, e.g., if you are using MacOS, you should download the macos_binary.zip file, and after unzip it your will find bnbcli (for mainet) and tbnbcli(for testnet). In the following, we will refer the binary as bnbcli for simplicity.

    "},{"location":"bc-fusion/validators/creation/#setup-account","title":"Setup account","text":"

    If you have mnemonic, you can import your account by running the following command:

    $ ${workspace}/bin/bnbcli keys add <your-account-name> --recover --home ${HOME}/.bnbcli\nEnter a passphrase for your key:\nRepeat the passphrase:\n> Enter your recovery seed phrase:\n

    You will be asked to set a password for this account and input your mnemonic. After that, you will get your account info.

    Or if you have a ledger, you can import your account by running the following command:

    ${workspace}/bin/bnbcli keys add <your-account-name> --ledger --index ${index} --home ${HOME}/.bnbcli\n
    "},{"location":"bc-fusion/validators/creation/#get-identity","title":"Get identity","text":"

    After the account is imported, you can get your identity by running the following command:

    For local key:

    ${workspace}/bin/bnbcli \\\n  validator-ownership \\\n  sign-validator-ownership \\\n  --bsc-operator-address ${NEW_VALIDATOR_OPERATOR_ADDR_ON_BSC} \\\n  --from ${ACCOUNT_NAME} \\\n  --chain-id ${BC_CHAIN_ID} \\\n

    For ledger key:

    ${workspace}/bin/bnbcli \\\n  validator-ownership \\\n  sign-validator-ownership \\\n  --bsc-operator-address ${NEW_VALIDATOR_OPERATOR_ADDR_ON_BSC} \\\n  --from ${BSC_OPERATOR_NAME} \\\n  --chain-id ${CHAIN_ID} \\\n  --ledger\n

    And you will get the output like this:

    TX JSON: {\"type\":\"auth/StdTx\",\"value\":{\"msg\":[{\"type\":\"migrate/ValidatorOwnerShip\",\"value\":{\"bsc_operator_address\":\"RXN7r5XZlaljqzp8msZvx6Y6124=\"}}],\"signatures\":[{\"pub_key\":{\"type\":\"tendermint/PubKeySecp256k1\",\"value\":\"Ahr+LlBMLgiUFkP75kIuJW1YHrsTy39GeOdV+IaTREDN\"},\"signature\":\"AL5mj52s0+tcdoEb6c6PAmqBixuv3XEmrLW3Y1kvUeYgG3RqVvWU/dIVcfxiHHwLGXlcn0X1v00jFrpLIsxtqA==\",\"account_number\":\"0\",\"sequence\":\"0\"}],\"memo\":\"\",\"source\":\"0\",\"data\":null}}\nSign Message:  {\"account_number\":\"0\",\"chain_id\":\"Binance-GGG-Ganges\",\"data\":null,\"memo\":\"\",\"msgs\":[{\"bsc_operator_address\":\"0x45737baf95d995a963ab3a7c9ac66fc7a63ad76e\"}],\"sequence\":\"0\",\"source\":\"0\"}\nSign Message Hash:  0x8f7179e7969e497b5f3c006535e55c2fa5bea5d118a8008eddce3fccd1675673\nSignature: 0x00be668f9dacd3eb5c76811be9ce8f026a818b1bafdd7126acb5b763592f51e6201b746a56f594fdd21571fc621c7c0b19795c9f45f5bf4d2316ba4b22cc6da8\nPubKey: 0x021afe2e504c2e08941643fbe6422e256d581ebb13cb7f4678e755f886934440cd\n

    The Signature is your identity for associating to the old validator created on the Beacon Chain.

    "},{"location":"bc-fusion/validators/creation/#commissions","title":"Commissions","text":""},{"location":"bc-fusion/validators/creation/#self-delegation","title":"Self-delegation","text":""},{"location":"bc-fusion/validators/creation/#3-submitting-the-form","title":"3. Submitting the form","text":"

    Once you have filled out all the required information, click the Submit button to submit the transaction.

    "},{"location":"bc-fusion/validators/gov/","title":"Governance","text":""},{"location":"bc-fusion/validators/gov/#governance","title":"Governance","text":"

    BEP-297 introduces the native governance module for BNB smart chain after BNB chain fusion. The governance module is derived from OpenZeppelin Governor, with the following features:

    "},{"location":"bc-fusion/validators/gov/#workflow","title":"Workflow","text":"

    The workflow of the governance module consists of three stages: submit proposal, cast vote, and execute proposal. Each stage has its own requirements and parameters, which can be configured by the BNB smart chain governance too.

    "},{"location":"bc-fusion/validators/gov/#submit-proposal","title":"Submit Proposal","text":"

    To submit a proposal, a staking credit holder needs to send a propose transaction to the Governor contract, which is a system contract and the address is 0x0000000000000000000000000000000000002004, specifying the following information:

    A delegator should delegate more the 200 staked BNB as the minimal requirement for submitting a proposal. Meanwhile, a delegator can only submit a new propopal if there is no pending proposal created by him/her. The propose transaction will create a new proposal on the BNB smart chain. The proposal will have a unique proposal ID, and a proposal status of Pending. The proposal will then enter the voting period, which is the time window for the staking credit holders to cast their votes on the proposal.

    "},{"location":"bc-fusion/validators/gov/#cast-vote","title":"Cast Vote","text":"

    To cast a vote on a proposal, a staking credit holder needs to send a castVote transaction to the Governor contract, specifying the following information:

    The castVote transaction will record the support value and the voting power of the voter on the BNB smart chain. The voting power is the amount of staking credit that the voter has at the time of the vote. The voting power can change due to staking operations, such as delegate, undelegate, or redelegate, but the support value will remain the same. The voter can change their support value at any time during the voting period, by sending another castVote transaction with a different support value.

    After submitting a proposal, the staking credit holders can cast their votes on the proposal until the voting period ends. The voting period is one of the BNB smart chain governance parameters, and it is currently set to 7 days.

    "},{"location":"bc-fusion/validators/gov/#execute-proposal","title":"Execute Proposal","text":"

    To execute a proposal, anyone can send an execute transaction to the Governor contract, specifying the following information:

    The execute transaction will check the proposal status and the voting results on the BNB smart chain, and determine whether the proposal can be executed or not. The proposal can be executed if the following conditions are met:

    Once the voting period is over, the proposal can be executed if it meets the required conditions. However, the proposal cannot be executed immediately, as there is a time lock period before the proposal is executed. The time lock period is another BNB smart chain governance parameter, and it is currently set to 1 day. The time lock period is designed to prevent sudden and irreversible changes on the BNB smart chain, and to give the stakeholders a chance to react or prepare for the proposal execution.

    "},{"location":"bc-fusion/validators/gov/#voting-power-delegation","title":"Voting Power Delegation","text":"

    In addition to casting votes, the staking credit holders can also delegate their voting power to someone else to participate in governance on their behalf. This can be useful for staking credit holders who do not have the time, interest, or expertise to follow and vote on the proposals, but still want to have a say in the governance process. By delegating their voting power to a trusted party, such as a validator, a friend, or a professional service, they can benefit from their knowledge and experience, and also avoid the risk of losing their staking rewards due to abstaining from voting.

    To delegate their voting power, a staking credit holder needs to send a delegateVote transaction to the GovToekn contract, which is a system contract and the address is 0x0000000000000000000000000000000000002005, specifying the following information:

    The delegateVote transaction will record the delegation relationship and the voting power of the delegator on the BNB smart chain. The voting power is the amount of staking credit that the delegator has at the time of the delegation. The voting power can change due to staking operations, such as delegate, undelegate, or redelegate, but the delegation relationship will remain the same. The delegator can change their delegatee address at any time, by sending another delegateVote transaction with a different delegatee address.

    "},{"location":"bc-fusion/validators/key-management/","title":"Key Management","text":""},{"location":"bc-fusion/validators/key-management/#key-management-for-bsc-validators","title":"Key Management for BSC Validators","text":"

    BEP-294 and BEP-297 introduce the native staking and governance features for BNB Smart Chain (BSC). For a validator, when participating in staking (e.g., creating a validator, self-delegating) and governance, there are several wallet keys that will be involved. To help validators manage their keys and funds effectively and safely, the following practices are recommended.

    "},{"location":"bc-fusion/validators/key-management/#operator-key","title":"Operator Key","text":"

    The operator key is used for operating a validator, including creating a validator, editing the information of a validator, and undelegating. When creating a validator, the operator key is also used for self-delegating with more than 2001 BNB. When interacting with the new BSC staking dApp, the operator key is mostly involved.

    Be noted that the operator address can not be changed for a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet; when creating validators, there should be more than 2001 BNB in the operator account.

    "},{"location":"bc-fusion/validators/key-management/#staking-key","title":"Staking Key","text":"

    For a validator, it can also use another key, different from the operator key, to manage his/her delegation if needed. Then, such a staking key will be used to delegate/undelegate/redelegate to different validators and claim rewards. This key could be used frequently, depending on how a validator manages its delegations and rewards.

    Be noted that this key is optional, depending on the needs of a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet.

    "},{"location":"bc-fusion/validators/key-management/#consensus-key","title":"Consensus Key","text":"

    The consensus key is used for signing proposed blocks when mining blocks. No fund is needed for this account.

    Recommendation: Use a hot wallet so that it can be easily accessed by a validator node.

    "},{"location":"bc-fusion/validators/key-management/#fast-finality-vote-key","title":"Fast Finality Vote Key","text":"

    The fast finality vote key (BLS vote key) is used in the fast finality feature for signing votes of recently mined blocks. No fund is needed for this account.

    Recommendation: Use a hot wallet so that it can be easily accessed by a validator node.

    "},{"location":"bc-fusion/validators/key-management/#governance-vote-key","title":"Governance Vote Key","text":"

    The BEP-297 introduces the native BSC staking feature. A delegator (including validators for self-delegation) can delegate someone else to participate in governance on his/her behalf. When there is governance delegation, the governance vote key will be used for casting votes to BSC proposals. The related wallet should store some BNB for gas fees of the voting transaction.

    Be noted that this key is optional, depending on the needs of a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet.

    "},{"location":"bc-fusion/validators/migrations/","title":"Migrate Your Validators","text":""},{"location":"bc-fusion/validators/migrations/#validator-migration-guide","title":"Validator Migration Guide","text":"

    The introduction of native staking on the BNB Smart Chain marks a significant milestone, enabling validators to be directly created and managed on the chain. Following the Feynman hardfork, validators initially established on the BNB Beacon Chain are required to migrate to the BNB Smart Chain to continue their operations.

    To migrate your validator, you can take the following steps:

    "},{"location":"bc-fusion/validators/migrations/#1-create-a-new-validator","title":"1. Create a new validator","text":"

    The Staking dApp offers a user-friendly interface for creating a new validator on the BNB Smart Chain. Follow the detailed instructions in the validator creation guide to set up your new validator. It\u2019s crucial to populate the Identity field as specified in the guide to ensure a successful migration.

    "},{"location":"bc-fusion/validators/migrations/#2-migrate-stakes-to-the-new-validator","title":"2. Migrate stakes to the new validator","text":"

    Once your new validator is active, inform your delegators about the migration. They will need to migrate their stakes to your new validator to continue supporting you. For comprehensive details on stake migration, refer to the stake migration guide.

    "},{"location":"bc-fusion/validators/slash/","title":"Slash","text":""},{"location":"bc-fusion/validators/slash/#slash","title":"Slash","text":"

    The BNB smart chain (BSC) is a blockchain network that aims to provide fast, secure, and reliable transactions. To achieve this, the BSC relies on a set of validators who are responsible for producing and validating blocks. Validators stake their BNB tokens to participate in the network and earn rewards.

    However, validators also face the risk of losing their stakes if they behave in ways that could harm the network\u2019s integrity and reliability. This is where the slashing mechanism comes in. The slashing mechanism is a set of rules and functions implemented in the SlashIndicator contract (which is a system contract and the address is 0x0000000000000000000000000000000000001001) that penalizes validators for violating certain conditions. The SlashIndicator contract will also calls the StakeHub contract, another system contract with address 0x0000000000000000000000000000000000002002, for slashing.

    The slashing mechanism covers three types of offenses: downtime, double signing, and malicious voting. Each offense has a different severity and penalty, depending on the impact it has on the network. In this document, we will explain the slashing conditions and mechanisms for each offense in detail.

    "},{"location":"bc-fusion/validators/slash/#downtime-slash","title":"Downtime Slash","text":"

    Validators are expected to maintain high availability to ensure the network\u2019s smooth operation. Validators failing to meet these uptime requirements are subject to slashing.

    "},{"location":"bc-fusion/validators/slash/#double-sign-slash","title":"Double Sign Slash","text":"

    A critical offense within the BSC network is when a validator signs two different blocks at the same height. Such actions can lead to network forks, undermining the blockchain\u2019s security and consistency. Anyone can send a submitDoubleSignEvidence transaction to the SlashIndicator contract, specifying the following information:

    "},{"location":"bc-fusion/validators/slash/#malicious-fast-finality-vote-slash","title":"Malicious Fast Finality Vote Slash","text":"

    Validators who violates the fast finality vote rules will be also slashed. Anyone can send a submitFinalityViolationEvidence transaction to the SlashIndicator contract, specifying the following information:

    "},{"location":"bc-fusion/validators/staking/","title":"Staking","text":""},{"location":"bc-fusion/validators/staking/#staking","title":"Staking","text":"

    BNB smart chain (BSC) is a Proof-of-Staked-Authority (PoSA) blockchain, which means that staking is one of the most important parts of the system. BEP-294 introduces the new native staking mechanism after BNB chain fusion, which has several differences:

    In this section, we will explain the basic concepts and operations of staking on the BSC.

    "},{"location":"bc-fusion/validators/staking/#basic-concepts","title":"Basic Concepts","text":""},{"location":"bc-fusion/validators/staking/#consensus-engine","title":"Consensus Engine","text":"

    BSC uses a consensus mechanism which combines DPoS and PoA for consensus, so that:

    The staking mechanism is essential for determining the eligibility of validators to produce blocks.

    "},{"location":"bc-fusion/validators/staking/#validator-set","title":"Validator Set","text":"

    The validator set is the group of nodes that are responsible for validating transactions and producing blocks on the BSC. The validator set is determined by the amount of staking each validator has, which reflects the amount of BNB staked by the validator and its delegators. The top validators with the most staking are selected as the active validator set, and they take turns to propose and vote on blocks. The rest of the validators are in the standby validator set, and they can join the active validator set if their staking increases or if some active validators drop out.

    Any organization or individual can become part of the validator set by creating their validator on-chain and securing sufficient delegations. Similarly, they can opt-out by simply withdrawing all their BNB delegations.

    Validators can also be removed from the validator set by slashing, which is a penalty for misbehaving or being offline.

    "},{"location":"bc-fusion/validators/staking/#validator-election","title":"Validator Election","text":"

    There are different rols for validators:

    To determinate the roles of all validators, the validator set is updated every 24 hours, based on the latest staking information. At the first block after UTC 00:00, the consensus engine will sort all the validators and update the BSC validator set contract to save the ranking information. Be noted: during the BC fusion, the validators created on Beacon Chain and the validators created on BSC will be sorted together to decide the top validators. However, the validators created on BSC will receive triple voting power compared with the validators created on Beacon Chain for the same amount of BNB staked.

    "},{"location":"bc-fusion/validators/staking/#sytems-contracts","title":"Sytems Contracts","text":"

    There are several built-in contracts (i.e., system contracts) to facilitate the BSC staking.

    "},{"location":"bc-fusion/validators/staking/#credit-contract","title":"Credit Contract","text":"

    Each validator has its own validator contract that manages staking credit and facilitates the exchange between credit and BNB. The token name of a staking credit is \u201cstake {{validator moniker}} credit\u201d, and the symbol is \u201cst{{validator moniker}}\u201d. The contract will be created by the Stake Hub Contract when a validator is created.

    Whenever a user delegates BNB, an equivalent quantity of credit tokens are created. On the other hand, when a user withdraws their delegation, a corresponding amount of credit tokens are destroyed, thereby releasing the BNB.

    "},{"location":"bc-fusion/validators/staking/#reward-distribution","title":"Reward Distribution","text":"

    The staking reward comes from transaction fee - when a block is produced, the majority of the block fee will be collected as reward for the validator who proposed the block. Every day, a portion of the rewards collected will be directly sent to the operator account of the validator as commission, while the remaining portion will be sent to the corresponding validator credit contract. And when a user undelegates and claims his/her stakes, the accumulated reward and the original stake will be sent back to him/her.

    "},{"location":"bc-fusion/validators/staking/#validator-operations","title":"Validator Operations","text":"

    Validators are nodes running BNB Smart Chain software, participating in the consensus process. They require a minimum BNB stake at their validator address and can receive delegations from other BNB holders. Validators earn rewards from transaction fees and share most of these rewards with their delegators.

    "},{"location":"bc-fusion/validators/staking/#create-validator","title":"Create Validator","text":"

    To create a validator, a BNB holder needs to send a CreateValidator transaction to the StakeHub contract, which is a system contract and the address is 0x0000000000000000000000000000000000002002, with minimum amount of BNB that the validator needs to stake to their own validator address (2000 BNB), specifying the following information:

    The CreateValidator transaction will deduct the minimum self-delegation amount from the validator address and issue the corresponding staking credit to the validator. The validator will then join the standby validator set, and wait for the next validator set update to see if they can enter the active validator set.

    "},{"location":"bc-fusion/validators/staking/#edit-validator","title":"Edit Validator","text":"

    A validator can edit their validator information by sending EditConsensusAddress, EditCommissionRate, EditDescription, EditVoteAddress transactions to the StakeHub contract, specifying the following information accordingly:

    These transactions will update the validator information on the BNB smart chain, and the changes will take effect immediately. However, the new commission rate will only apply to the rewards earned after the transaction, and the previous rewards will be distributed according to the previous commission rate.

    "},{"location":"bc-fusion/validators/staking/#delegator-operations","title":"Delegator Operations","text":"

    Delegators are BNB holders who stake their BNB with a validator, sharing rewards. They can select any active or standby validator, switch between them, undelegate their BNB, and claim rewards anytime.

    "},{"location":"bc-fusion/validators/staking/#delegate","title":"Delegate","text":"

    To delegate BNB to a validator, a BNB holder needs to send a Delegate transaction to the StakeHub contract, specifying the following information:

    The Delegate transaction will deduct the amount of BNB from the delegator address and issue the corresponding staking credit to the validator. The validator will then share the rewards with the delegator, according to the commission rate.

    The credit tokens (or share) a delgator will get is calculated as - delegation amount * total supply of credit token / total pooled BNB. The total pooled BNB includes the delegation BNB and unclaimed reaward BNB of of the vlidator. It means that a delegator will get credit tokens based on the ratio of his/her delegation BNB amount to the total staked and reward BNB. When the validator gets block reward the total pooled BNB amount will increase, which means that when unbonding the delegator will get his delegation, as well as reward BNB from the pool.

    "},{"location":"bc-fusion/validators/staking/#redelegate","title":"Redelegate","text":"

    To redelegate BNB from one validator to another, a delegator needs to send a Redelegate transaction to the StakeHub contract, specifying the following information:

    The Redelegate transaction will deduct the amount of source validator staking credit and issue the corresponding dest validator staking credit to the user. The destination validator will then share the rewards with the delegator, according to the commission rate of the destination validator.

    The Redelegate transaction does not incur the unbonding period, but it will incur the redelegation fee, which is designed to prevent delegators from frequently switching between validators to chase the highest rewards or avoid the highest risks. The current fee rate is 0.002%.

    "},{"location":"bc-fusion/validators/staking/#undelegate","title":"Undelegate","text":"

    To undelegate BNB from a validator, a delegator needs to send an Undelegate transaction to the StakeHub contract, specifying the following information:

    The Undelegate transaction will burn the amount of staking credit from the user and moves the BNB to a withdraw queue. The BNB gets locked for an unbonding period before the delegator can claim it. The unbonding period is currently set to 7 days, and it is designed to prevent delegators from quickly withdrawing their BNB in case of a validator misbehavior or a network attack.

    "},{"location":"bc-fusion/validators/staking/#claim","title":"Claim","text":"

    To claim the unbond BNB and the rewards, a delegator should send a Claim transaction to the StakeHub contract, specifying the following information:

    The Claim transaction will return the delegated BNB and rewards to the delegator. Be noted, a delegator can only get the rewards after unbond. Before undelegation, the reward will be furthur staked to boost a delegator\u2019s income.

    "},{"location":"bnb-greenfield/","title":"BNB Greenfield","text":"BNB Greenfield

    BNB Greenfield is a cutting-edge decentralized storage and blockchain storage solution, designed to harness the power of decentralized technology in the field of data ownership and the data economy. The platform focuses on providing decentralized data management and access and EVM programmability, to revolutionize the data economy by simplifying the process of storing and managing data, while connecting data ownership with the DeFi context of BNB Chain.

    Get Started

    Dive into what is BNB Greenfield and start the journey with Greenfield.

    Build on Greenfield

    Start building dapps to create value based on the data assets and its related economy.

    EVM Programmability

    The real power of the Greenfield lies in its programmability to support the creation of value based on the data assets and its related economy.

    Greenfield Blockchain

    Get familiar with the Greenfield Blockchain and explore its main modules.

    Storage Provider

    Explore the Storage Provider.

    APIs and SDKs

    Utilize the APIs and SDKs to build the app

    "},{"location":"bnb-greenfield/introduction/","title":"Overview","text":""},{"location":"bnb-greenfield/introduction/#bnb-greenfield-overview","title":"BNB Greenfield Overview","text":"

    BNB Greenfield is a decentralized storage and blockchain storage solution platform that aims to revolutionize data ownership and the data economy.

    "},{"location":"bnb-greenfield/introduction/#what-is-bnb-greenfield","title":"What is BNB Greenfield","text":"

    BNB Greenfield is a cutting-edge decentralized storage and blockchain storage solution, designed to harness the power of decentralized technology in the field of data ownership and the data economy. The platform focuses on providing decentralized data management and access, to revolutionize the data economy by simplifying the process of storing and managing data, while connecting data ownership with the DeFi context of BNB Chain.

    What sets Greenfield apart from existing centralized and decentralized storage systems are its three key components:

    The ultimate goal of Greenfield is to establish a foundation for new data economy and dApp models, which will undoubtedly aid in the development and evolution of the foundation for Web3.

    "},{"location":"bnb-greenfield/introduction/#why-bnb-greenfield","title":"Why BNB Greenfield","text":"

    The cryptocurrency industry has experienced significant growth and adoption, with the likes of tokens, stablecoins, and DeFi covering various economic scenarios. However, certain areas like credit, real-world asset (RWA) tokenizations, and data remain inadequately innovated. Consequently, BNB Greenfield has been created to focus on data.

    A crucial issue that the BNB Greenfield project aims to address is that the value of a data asset is not self-evident when held by one person. The value of data assets increases when shared and leveraged by multiple parties, which stems from the ability to write, read, grant rights for sharing data, and even execute data to generate another. These abilities have financial traits that are tradable, and such trades can produce even more value and benefit two parties rather than just one.

    We foresee the need to create a new Web3 infrastructure for data, as two major features are still missing: a performant, convenient, and friendly decentralized storage infra, and the data-focused smart contract synergy. Hence, we aim to create \u201cBNB Greenfield,\u201d a new BNB side blockchain and relevant infrastructure that allows users and developers to:

    1. \u201clogin\u201d with anonymous cryptographic-based keys (IDs);

    2. create, read, share, and even execute data, with a user experience that is on par with the state-of-the-art cloud storage services today, and at a low cost;

    3. fully own their data assets and control who can use them and how;

    4. easily put their data assets into a wide, smart-contract-based economic context to gain financial value with them.

    In summary, BNB Greenfield seeks to offer users greater freedom in creating, owning, sharing, executing, and trading their data assets, while also providing transparency on how their data is owned and used.

    "},{"location":"bnb-greenfield/introduction/#how-bnb-greenfield-works","title":"How BNB Greenfield Works","text":"

    BNB Greenfield operates on two layers:

    1. It is built on a new, storage-focused blockchain; and

    2. It consists of a network of \u201cstorage providers\u201d.

    The BNB Greenfield Blockchain maintains the ledger for users and records the storage metadata as the common blockchain state data. Its native token for gas and governance is BNB, which is transferred from BNB Smart Chain. Additionally, BNB Greenfield blockchain has its own staking logic designed for governance.

    The Storage Providers (SP) are storage service infrastructures provided by organizations or individuals that use Greenfield as the ledger and the single source of truth. Each SP is responsible for responding to user requests to upload and download data, while also serving as the gatekeeper for user rights and authentications.

    Together, BNB Greenfield blockchain and the SPs comprise a decentralized object storage system that serves as the core of this new economy. Developers can construct decentralized applications (dApps) using the BNB Greenfield platform, which can act as client tools that facilitate user interactions with Greenfield; or applications that provide significant value to users\u2019 real lives using Greenfield as their infrastructure. These applications will use blockchain addresses as user identifiers and connect with features and smart contracts on the Greenfield blockchain, Greenfield SPs, and BNB Chain.

    A native cross-chain bridge exists between BSC and BNB Greenfield blockchain. While it is cheaper to create and access data on Greenfield, the relevant data operation can be transferred to BSC and integrated with DeFi smart contract systems to generate new business models.

    "},{"location":"bnb-greenfield/introduction/#ecosystem","title":"Ecosystem","text":"

    From Storage Providers and BNB staker to developers, there are a variety of individuals and entities that play a critical role in the growth and success of Greenfield. We\u2019ll dive into the unique contributions and responsibilities of each group, and explore how they work together to shape the future of Greenfield.

    "},{"location":"bnb-greenfield/introduction/#greenfield-actors","title":"Greenfield Actors","text":""},{"location":"bnb-greenfield/introduction/#validators","title":"Validators","text":"

    The Greenfield blockchain operates as a Proof-of-Stake (PoS) blockchain and has its own set of validators chosen through an election process based on PoS logic.

    The Validators have a vital responsibility of ensuring the security of the Greenfield blockchain. They are actively involved in the governance and staking of the blockchain, and their role is similar to other PoS blockchain networks. Additionally, they form a peer-to-peer network that plays a crucial role in the overall functioning of the blockchain.

    In addition to their governance responsibilities, validators also accept and process transactions, which enables users to operate on the objects stored on the Greenfield blockchain. They are responsible for maintaining the metadata of Greenfield and ensure that the blockchain state acts as a control panel for both Storage Providers (SPs) and users. Both parties rely on the validators to accurately update and utilize this state in order to operate, store, and access their object storage.

    "},{"location":"bnb-greenfield/introduction/#storage-providers-sps","title":"Storage Providers (SPs)","text":"

    Storage Providers (SPs) are a crucial part of the Greenfield blockchain. They offer storage service infrastructures to individuals and organizations. Using the Greenfield blockchain as the ledger and single source of truth, SPs maintain secure and reliable storage.

    Each Service Provider (SP) is accountable for handling user requests to upload and download data. They act as gatekeepers for user rights and authentications, which makes them integral in ensuring the security and accessibility of user data at all times.

    For further details on storage providers, kindly explore our dedicated Storage Provider\u2019s page.

    "},{"location":"bnb-greenfield/introduction/#greenfield-features","title":"Greenfield Features","text":""},{"location":"bnb-greenfield/introduction/#dapps","title":"dApps","text":"

    Greenfield dApps are applications that leverage the unique features of the Greenfield blockchain to solve various problems for their users. These dApps are designed to utilize Greenfield storage and related economic traits, providing a reliable and secure platform for creating and managing data.

    Users can interact with the BNB Greenfield Core Infrastructure through the use of BNB Greenfield dApps, which are decentralized applications that enable seamless interaction with the Greenfield ecosystem. Furthermore, the Greenfield blockchain provides an intuitive smart contract library on the cross-chain facility, making it easy for dApp developers to integrate these features into their applications. This user-friendly approach allows developers to efficiently build and deploy dApps that can solve real-world problems.

    "},{"location":"bnb-greenfield/introduction/#relayers","title":"Relayers","text":"

    The Greenfield Relayer is a powerful bi-directional relaying service designed to facilitate seamless communication between Greenfield and BSC/opBNB. It can only be operated by Greenfield validators and functions as a standalone process.

    This innovative system independently monitors and tracks cross-chain events that take place on both the Greenfield and BSC/opBNB networks, storing this data securely in a database. When an event is confirmed, the relayer generates a Boneh\u2013Lynn\u2013Shacham (BLS) signed message that is then shared through the P2P network on the Greenfield network, known as \u201cthe vote\u201d.

    As more votes are collected, the Greenfield Relayer assembles the necessary cross-chain package transaction and submits it to either the BSC/opBNB or Greenfield network. This streamlined process ensures that communication between the two networks is efficient and error-free.

    "},{"location":"bnb-greenfield/introduction/#challenge-verifier","title":"Challenge Verifier","text":"

    Challenge Verifier is an off-chain service that verifies data availability, data integrity and service quality by monitoring storage provider\u2019s activities. This mechanism works by penalizing and gradually eliminating storage providers with poor service quality, in order to ensure the good performance and reliability of the entire network.

    To elaborate, Challenge Verifier constantly checks the storage providers in the network by tasking them with challenges to prove their reliability. The challenges may include storing specific pieces of data or responding to requests within a certain time limit. Providers that fail these challenges will be punished by slash their staked BNB.

    By using Challenge Verifier, the network can ensure that only reliable and trustworthy storage providers are allowed to participate, protecting the network from any potential data loss, corruption, or low-quality service. Additionally, Challenge Verifier creates a competitive environment for storage providers, motivating them to continuously improve their services to avoid penalties and stay in the network.

    Challenge Verifier can only be operated by Greenfield validators right now, and will open to public in the future.

    "},{"location":"bnb-greenfield/introduction/#explore-and-participate-in-bnb-greenfield","title":"Explore and Participate in BNB Greenfield","text":""},{"location":"bnb-greenfield/core-concept/accounts/","title":"Accounts - BNB Greenfield Core Concepts","text":""},{"location":"bnb-greenfield/core-concept/accounts/#accounts","title":"Accounts","text":"

    Each Greenfield user has their own address as the identifier for his/her account. The addresses can create objects to store on Greenfield, bear and manage the permissions, and pay fees.

    Greenfield defines its account in the same format as BSC and Ethereum. It starts with ECDSA secp256k1 curve for keys and is compliant with EIP84 for full BIP44 paths. The root HD path for Greenfield-based accounts is m/44\u2019/60\u2019/0\u2019/0. In the readable presentation, a Greenfield address is a 42-character hexadecimal string derived from the last 20 bytes of the public key of the controlling account with 0x as the prefix.

    With this compatible address scheme, the users can reuse existing accounts and infrastructure from BSC on Greenfield. For example, they can use TrustWallet and Metamask (or other compatible wallets) to deposit their BNB from BSC to Greenfield and interact with dApps on Greenfield. It is also easy to identify the same owner by referring to the same addresses on both BSC and Greenfield.

    "},{"location":"bnb-greenfield/core-concept/accounts/#user-balance","title":"User Balance","text":"

    The account can hold a balance of BNB. These BNBs can be used to participate in staking, pay for gas fees of Greenfield transactions, and pay for Greenfield services.

    This balance can be added via native BNB transfer on Greenfield, or cross-chain transfer between Greenfield and BSC.

    "},{"location":"bnb-greenfield/core-concept/accounts/#account-definition","title":"Account Definition","text":"

    In the Greenfield, an account designates a pair of PubKey and PrivKey. The PubKey can be derived to generate various Addresses, which are used to identify users (among other parties) in the application.

    "},{"location":"bnb-greenfield/core-concept/accounts/#signatures","title":"Signatures","text":"

    The principal way of authenticating a user is done using digital signatures. Users sign transactions using their own private key. Signature verification is done with the associated public key. For on-chain signature verification purposes, we store the public key in an Account object (alongside other data required for a proper transaction validation).

    In the node, all data is stored using Protocol Buffers serialization.

    Greenfield only supports secp256k1 key schemes for creating digital signatures:

    Address length in bytes Public key length in bytes Used for transaction authentication Used for consensus (Tendermint) secp256k1 20 33 yes no"},{"location":"bnb-greenfield/core-concept/accounts/#addresses","title":"Addresses","text":"

    Addresses and PubKeys are both public information that identifies actors in the application. Account is used to store authentication information. The basic account implementation is provided by a BaseAccount object.

    To identify users, Greenfield uses the variable AccAddress. The address format follows ERC-55.

    "},{"location":"bnb-greenfield/core-concept/accounts/#key-management","title":"Key Management","text":"

    Greenfield blockchain is an application-specific chain without EVM. As a result, its transaction data structure and API are different from those of BSC. Greenfield will not support full functions in existing wallets, e.g. Transfer, Send Transactions, etc. However, these wallets can still sign transactions using the EIP712 standard. This standard allows wallets to display data in signing prompts in a structured and readable format. This is an example of how to use it in Metamask. Eventually, wallets will start supporting Greenfield directly.

    "},{"location":"bnb-greenfield/core-concept/accounts/#eip-712-support","title":"EIP-712 Support","text":"

    The greenfield chain supports and only supports EIP-712 structured transaction. These enable the existing wallet infrastructure to interact with Greenfield at the beginning naturally.

    To achieve this, the following changes have been made.

    1. An Ethereum-compatible RPC backend. Be noted that we only support necessary methods to connect a wallet(eth_chainId, eth_networkId, eth_blockNumber, eth_getBlockByNumber and eth_getBalance). Other RPC methods are not implemented.
    2. Same signing algorithm(eth_scep256k1) as Ethereum.

    For developers, they can refer to greenfield-go-sdk and greenfield-js-sdk for easy integration.

    "},{"location":"bnb-greenfield/core-concept/accounts/#keyring-interface","title":"Keyring Interface","text":"

    The Keyring interface is the primary interface for key management in the greenfield-cosmos-sdk. It defines the methods that a type needs to implement to be used as a key storage backend. These methods include:

    By implementing these methods, you can create a custom key storage backend that meets the specific needs of your application.

    Tip

    It means you don\u2019t have to follow the Keyring interface to manage your key, any existing Ethereum wallets are applicable to

    Greenfield as well.

    "},{"location":"bnb-greenfield/core-concept/accounts/#backend-options","title":"Backend Options","text":"

    The greenfield-cosmos-sdk provides different options for key storage, each with its own strengths and weaknesses. The choice of backend will depend on your specific use case. Here are the available options:

    "},{"location":"bnb-greenfield/core-concept/accounts/#system-options","title":"System Options","text":""},{"location":"bnb-greenfield/core-concept/accounts/#tools-options","title":"Tools Options","text":""},{"location":"bnb-greenfield/core-concept/accounts/#supported-sign-algorithms","title":"Supported Sign Algorithms","text":"

    The greenfield-cosmos-sdk supports as many sign algorithms as users want, but in Greenfield context, we only support eth_secp256k1 and ed25519. These algorithms were chosen for their security and compatibility with the Ethereum and Tendermint ecosystems.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/","title":"Billing and Payment - BNB Greenfield Core Concepts","text":""},{"location":"bnb-greenfield/core-concept/billing-payment/#billing-and-payment","title":"Billing and Payment","text":"

    In Greenfield, users are required to pay two different types of fees:

    The storage service fee will be charged on Greenfield in a steam payment style like Superfluid.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#storage-service-fee","title":"Storage Service Fee","text":"

    There are two kinds of storage service fees in Greenfield: object storage fee and data package fee.

    For storage, every object stored on Greenfield is charged at the price calculated by size, replica numbers, a base price ratio, and other parameters. Once the object is stored, the total charge of storage will be mainly only related to time and the base price.

    The storage fee calculation is:

    Storage Fee = sum(ChargedSize) * (PrimaryStorePrice + SecondaryStorePrice*SecondarySPNumber) * (1+Validator Tax Rate) * ReserveTime\n

    Users are granted a free, time-based quota for downloading data, with each bucket corresponding to a set of their objects. If the quota is exceeded, users can upgrade their data package to obtain an additional quota. The price for each data package is fixed for a certain period (unless the read price has been changed and the user takes some actions to reflect the price change), during which users will only be charged based on the amount of time they spend downloading and the package price. This charging scheme remains in effect until the user modifies their data package settings.

    The download quota fee calculation is:

    Download Quota Fee Fee = ChargedReadQuota * ReadPrice * (1 + Validator Tax Rate) * ReserveTime\n
    "},{"location":"bnb-greenfield/core-concept/billing-payment/#global-virtual-group-family-global-virtual-group","title":"Global Virtual Group Family & Global Virtual Group","text":"

    For storage fees, it will be not streamed to storage providers directly. It will be streamed to:

    When storage providers want to get their income, they can withdraw from Global Virtual Group Family and Global Virtual Group they are in. The validator tax pool cannot be controlled via any private key, and is used for challenge reward.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#payment-account","title":"Payment Account","text":"

    By default, the object owner\u2019s address will be used to pay for the objects it owns. But users can also create multiple \u201cpayment accounts\u201d and associate objects to different payment accounts to pay for storage and bandwidth.

    The address format of the payment account is the same as normal accounts. It\u2019s derived by the hash of the user address and payment account index. However, the payment accounts are only logical ones and only exist in the storage payment module. Users can deposit into, withdraw from, and query the balance of payment accounts on the Greenfield blockchain, but users cannot use payment accounts to perform staking or other on-chain transactions. Payment accounts can be set as \u201cnon-refundable\u201d. Users cannot withdraw funds from such payment accounts.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#paymaster","title":"Paymaster","text":"

    Besides using the owner\u2019s address or payment accounts to pay for the storage and bandwidth, users can also use others\u2019 address or payment account by setting the payment account for the bucket. The owner of payment account need to set the flow rate limit for the bucket before the bucket can be used.

    This will lower the barrier for users to use Greenfield since they don\u2019t need to have BNB to pay for the storage and bandwidth and they don\u2019t need to understand the charging mechanism of Greenfield which is quite complex.

    It will also provide a possibility for projects to sponsor the storage and bandwidth for their users.

    For more details, you can refer to the BEP of the paymaster.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#downgraded-service","title":"Downgraded service","text":"

    Once the payment accounts run out of BNB, the objects associated with these payment accounts will suffer from a downgraded service of downloading, i.e. the download speed and connection numbers will be limited. Once the fund is transferred to the payment accounts, the service quality can be resumed right away. If the service is not resumed for a long time, it is the SPs\u2019 discretionary decision to clear the data out, in a similar way to how SPs claim to stop services to certain objects. In such a case, the data may be gone from Greenfield completely.

    Warning

    If users fail to renew their subscription on time, there is a risk of their stored data being permanently deleted.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#trust-or-shift","title":"Trust or Shift","text":"

    In Greenfield, there is trust between the users and the SPs for data download.

    Since downloading bandwidth incurs additional fees and the download journal is not completely stored on the Greenfield blockchain, SPs offer an endpoint interface for users to access detailed logs and downloaders\u2019 signatures for download billing. If the users and the SPs cannot agree on the bill, users may just select another Primary SP.

    For more tech details, please refer to the stream payment module design.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#gas-and-fees","title":"Gas and Fees","text":"

    This document describes how Greenfield charge fee to different transaction types and the token economics of BNB Greenfield.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#introduction-to-gas-and-fees","title":"Introduction to Gas and Fees","text":"

    In the Cosmos SDK, gas unit is designated to track resource consumption during execution.

    On application-specific blockchains such as Greenfield, computational cost of storage is no longer the main factor in determining transaction fees, but rather, it is the incentive mechanism of Greenfield. For instance, creating and deleting a storage object use similar I/O and computational resources, but Greenfield encourages users to delete unused storage objects to optimize storage space, resulting in lower transaction fees.

    Greenfield Blockchain has taken a different approach from the gas meter design in Cosmos SDK. Instead, it has redesigned the gashub module to calculate gas consumption based on the type and content of the transaction, rather than just the consumption of storage and computational resources.

    Unlike networks like Ethereum, Greenfield transactions do not feature a gas price field. Instead, they consist of a fee and a gas-wanted field. The gas price is inferred during the transaction pre-execution process by fee/gas-wanted, and the transactions are queued based on the gas price, besides that the gas price should not be less than the minimum gas price on Greenfield: 5gwei.

    Warning

    This means that Greenfield does not refund any excess gas fees to the transaction sender.

    Therefore, when constructing transactions, it is important to exercise caution when specifying the fees.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#gashub","title":"GasHub","text":"

    All transaction types need to register their gas calculation logic to gashub. Currently, four types of calculation logic are supported:

    MsgGasParams_FixedType:

    type MsgGasParams_FixedType struct {\n    FixedType *MsgGasParams_FixedGasParams \n}\n

    MsgGasParams_GrantType:

    type MsgGasParams_GrantType struct {\n    GrantType *MsgGasParams_DynamicGasParams \n}\n

    MsgGasParams_MultiSendType:

    type MsgGasParams_MultiSendType struct {\n    MultiSendType *MsgGasParams_DynamicGasParams \n}\n

    MsgGasParams_GrantAllowanceType:

    type MsgGasParams_GrantAllowanceType struct {\n    GrantAllowanceType *MsgGasParams_DynamicGasParams \n}\n
    "},{"location":"bnb-greenfield/core-concept/billing-payment/#block-gas-meter","title":"Block Gas Meter","text":"

    ctx.BlockGasMeter() serves as the gas meter designed to monitor and restrict gas consumption per block.

    However, certain types of transactions may incur a high cost in Greenfield, leading to significant gas consumption. Consequently, Greenfield refrains from imposing any gas usage constraints on a block. Instead, Greenfield sets a block size limit, preventing blocks from exceeding 1MB in size and mitigating the risk of excessively large blocks.

    Info

    There is no gas limitation of a block on Greenfield Blockchain.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#fee-table","title":"Fee Table","text":"

    Please note that the gas fee can be updated through governance and may not be immediately reflected in this documentation.

    Msg Type Gas Used Gas Price Expected Fee(assuming BNB $200) /cosmos.auth.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.bank.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.consensus.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.crisis.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.crosschain.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.crosschain.v1.MsgUpdateChannelPermissions 0 5 gwei $0.00000000 /cosmos.distribution.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.gashub.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.gov.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.mint.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.oracle.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.slashing.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.staking.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.bridge.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.sp.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.storage.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.payment.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.challenge.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.permission.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.authz.v1beta1.MsgExec 1200 5 gwei $0.00120000 /cosmos.authz.v1beta1.MsgRevoke 1200 5 gwei $0.00120000 /cosmos.bank.v1beta1.MsgSend 1200 5 gwei $0.00120000 /cosmos.distribution.v1beta1.MsgSetWithdrawAddress 1200 5 gwei $0.00120000 /cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward 1200 5 gwei $0.00120000 /cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission 1200 5 gwei $0.00120000 /cosmos.feegrant.v1beta1.MsgRevokeAllowance 1200 5 gwei $0.00120000 /cosmos.gov.v1.MsgDeposit 1200 5 gwei $0.00120000 /cosmos.gov.v1.MsgSubmitProposal 2000000 5 gwei $2.00000000 /cosmos.gov.v1.MsgVote 2000000 5 gwei $2.00000000 /cosmos.gov.v1.MsgVoteWeighted 2000000 5 gwei $2.00000000 /cosmos.oracle.v1.MsgClaim 1000 5 gwei $0.00100000 /cosmos.slashing.v1beta1.MsgUnjail 1200 5 gwei $0.00120000 /cosmos.staking.v1beta1.MsgBeginRedelegate 1200 5 gwei $0.00120000 /cosmos.staking.v1beta1.MsgCancelUnbondingDelegation 1200 5 gwei $0.00120000 /cosmos.staking.v1beta1.MsgCreateValidator 2000000 5 gwei $2.00000000 /cosmos.staking.v1beta1.MsgDelegate 1200 5 gwei $0.00120000 /cosmos.staking.v1beta1.MsgEditValidator 2000000 5 gwei $2.00000000 /cosmos.staking.v1beta1.MsgUndelegate 1200 5 gwei $0.00120000 /greenfield.bridge.MsgTransferOut 1200 5 gwei $0.00120000 /greenfield.sp.MsgCreateStorageProvider 2000000 5 gwei $2.00000000 /greenfield.sp.MsgDeposit 1200 5 gwei $0.00120000 /greenfield.sp.MsgEditStorageProvider 2000000 5 gwei $2.00000000 /greenfield.sp.MsgUpdateSpStoragePrice 2000000 5 gwei $2.00000000 /greenfield.sp.MsgUpdateStorageProviderStatus 1200 5 gwei $0.00120000 /greenfield.storage.MsgCreateBucket 2400 5 gwei $0.00240000 /greenfield.storage.MsgDeleteBucket 1200 5 gwei $0.00120000 /greenfield.storage.MsgMirrorBucket 1200 5 gwei $0.00120000 /greenfield.storage.MsgUpdateBucketInfo 1200 5 gwei $0.00120000 /greenfield.storage.MsgCreateObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgSealObject 120 5 gwei $0.00012000 /greenfield.storage.MsgMirrorObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgRejectSealObject 12000 5 gwei $0.01200000 /greenfield.storage.MsgDeleteObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgCopyObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgCancelCreateObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgUpdateObjectInfo 1200 5 gwei $0.00120000 /greenfield.storage.MsgDiscontinueObject 2400 5 gwei $0.00240000 /greenfield.storage.MsgDiscontinueBucket 2400 5 gwei $0.00240000 /greenfield.storage.MsgCreateGroup 2400 5 gwei $0.00240000 /greenfield.storage.MsgDeleteGroup 1200 5 gwei $0.00120000 /greenfield.storage.MsgLeaveGroup 1200 5 gwei $0.00120000 /greenfield.storage.MsgUpdateGroupMember 1200 5 gwei $0.00120000 /greenfield.storage.MsgUpdateGroupExtra 1200 5 gwei $0.00120000 /greenfield.storage.MsgRenewGroupMember 1200 5 gwei $0.00120000 /greenfield.storage.MsgMirrorGroup 1200 5 gwei $0.00120000 /greenfield.storage.MsgPutPolicy 2400 5 gwei $0.00240000 /greenfield.storage.MsgDeletePolicy 1200 5 gwei $0.00120000 /greenfield.storage.MsgMigrateBucket 1200 5 gwei $0.00120000 /greenfield.storage.MsgCancelMigrateBucket 1200 5 gwei $0.00120000 /greenfield.storage.MsgCompleteMigrateBucket 1200 5 gwei $0.00120000 /greenfield.payment.MsgCreatePaymentAccount 200000 5 gwei $0.20000000 /greenfield.payment.MsgDeposit 1200 5 gwei $0.00120000 /greenfield.payment.MsgWithdraw 1200 5 gwei $0.00120000 /greenfield.payment.MsgDisableRefund 1200 5 gwei $0.00120000 /greenfield.challenge.MsgSubmit 1200 5 gwei $0.00120000 /greenfield.challenge.MsgAttest 100 5 gwei $0.00010000 /greenfield.virtualgroup.MsgCreateGlobalVirtualGroup 1000000 5 gwei $1.00000000 /greenfield.virtualgroup.MsgDeleteGlobalVirtualGroup 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgDeposit 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgWithdraw 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgSettle 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgSwapOut 24000 5 gwei $0.02400000 /greenfield.virtualgroup.MsgCompleteSwapOut 24000 5 gwei $0.02400000 /greenfield.virtualgroup.MsgCancelSwapOut 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgReserveSwapIn 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgCancelSwapIn 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgCompleteSwapIn 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgStorageProviderExit 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgStorageProviderForcedExit 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgCompleteStorageProviderExit 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgUpdateParams 1200 5 gwei $0.00120000 cosmos.authz.v1beta1.MsgGrant 800 + 800 per item 5 gwei $0.0008 per item cosmos.bank.v1beta1.MsgMultiSend 800 + 800 per item 5 gwei $0.0008 per item cosmos.feegrant.v1beta1.MsgGrantAllowance 800 + 800 per item 5 gwei $0.0008 per item

    For more details, you can refer to Greenfield Gas Params.

    "},{"location":"bnb-greenfield/core-concept/bnb-token-model/","title":"BNB Token Model - BNB Greenfield Core Concepts","text":""},{"location":"bnb-greenfield/core-concept/bnb-token-model/#bnb-token-model","title":"BNB Token Model","text":"

    BNB remains the main utility token on Greenfield. BNB can be transferred from BSC to Greenfield blockchain, and vice versa. It is used as:

    "},{"location":"bnb-greenfield/core-concept/bnb-token-model/#revenue-sharing","title":"Revenue Sharing","text":"

    The main economic drive of Greenfield comes from their storage providers who charge users fees for their storage services. Meanwhile, validators play a crucial role in supervising the network\u2019s security, maintaining stability and ensuring service quality. While validators may earn transaction fees, this alone may not be enough to guarantee sufficient staking for network security. Therefore, Greenfield has designed validators to receive a reasonable proportion of fees from the storage services they provide. This approach ensures that users\u2019 data is not only stored but that the network is also safe and secure.

    "},{"location":"bnb-greenfield/core-concept/bnb-token-model/#circulation-model","title":"Circulation Model","text":"

    In Greenfield, there is no inflation of BNB because of its dual-chain structure. Instead, cross-chain transfers are used to allow BNB to flow bi-directionally between Greenfield and Smart Chain. As a result, the total circulation of BNB on Greenfield can fluctuate.

    Greenfield use Lock/Unlock mechanism to ensure the total circulation of BNB on both chain is always less than the initial total supply:

    1. The transfer-out blockchain will lock the amount from source owner addresses into a module account or smart contract.

    2. The transfer-in blockchain will unlock the amount from module account or contract and send it to target addresses.

    3. Both networks will never mint BNB.

    Refer to cross chain model to get more details about the mechanism.

    "},{"location":"bnb-greenfield/core-concept/bnb-token-model/#genesis-setup","title":"Genesis Setup","text":"

    BNB is transferred from BSC to Greenfield as the first cross-chain action. The initial validator set and storage provider of Greenfield at the genesis will first lock a certain amount of BNB into the \u201cGreenfield Token Hub\u201d contract on BSC. This contract is used as part of the native bridge for BNB transferring after the genesis. These initial locked BNB will be used as the self-stake of validators, the deposit of storage provider and early days gas fees.

    The initial BNB allocation on greenfield is around 500K BNB.

    Tip

    No initial donors, foundation, or company will get funds in the genesis setup.

    "},{"location":"bnb-greenfield/core-concept/programmability/","title":"Cross-Chain Programmability - BNB Greenfield Cross Chain","text":""},{"location":"bnb-greenfield/core-concept/programmability/#cross-chain-programmability","title":"Cross-Chain Programmability","text":"

    The Greenfield ecosystem leverages cross-chain programmability to enhance data asset value through innovative permission management and smart code execution. This platform supports the creation, management, and operation of data-intensive, trustless computing environments across different blockchains.

    Info

    It does not mean developers have to build dapp based on BSC network. Excellent infrastructure, applications, and tools can be built directly on the Greenfield network.

    "},{"location":"bnb-greenfield/core-concept/programmability/#framework","title":"Framework","text":"

    The Greenfield ecosystem is structured into three primary layers, each serving a distinct purpose in facilitating cross-chain interactions and asset management.

    This layered architecture ensures robust cross-chain capabilities, enabling developers to create innovative applications while utilizing Greenfield\u2019s unique features.

    "},{"location":"bnb-greenfield/core-concept/programmability/#key-features","title":"Key Features","text":""},{"location":"bnb-greenfield/core-concept/programmability/#get-started-with-building-dapp","title":"Get Started with building dapp","text":""},{"location":"bnb-greenfield/core-concept/data-storage/data-availability/","title":"Data Integrity and Availability - BNB Greenfield Data Storage","text":""},{"location":"bnb-greenfield/core-concept/data-storage/data-availability/#data-integrity-and-availability","title":"Data Integrity and Availability","text":"

    There are three crucial aspects of data management: integrity, availability, and redundancy.

    Below are some key points to ensure each aspect is met: - The primary storage provider must correctly store the object uploaded by the user. - The assigned data segments in both primary and secondary storage providers must be free of any loss, corruption, or counterfeit data. - Erasure coding pieces in secondary providers should enable recovery of the original data in the primary storage provider.

    To ensure data integrity and redundancy, checksum and redundancy setups must be established for objects. These setups constitute part of the objects\u2019 metadata and must be verified by the storage providers and users upon creating objects. The metadata will be stored on the Greenfield blockchain.

    Collaboration between Greenfield and storage providers is crucial to ensure data integrity and availability, particularly in assigning data segments to primary and secondary storage providers. To increase user confidence that their data is stored as promised, Greenfield has introduced a \u201cProof-of-Challenge\u201d approach.

    Info

    \u201cProof-of-Challenge\u201d is proposed based on the assumptions: Greenfield is a self-sustained, service-oriented ecosystem.

    Stakeholders can trigger challenges in various ways, such as through users or via random events on the Greenfield blockchain. Following a challenge, Challenge Verifier must conduct an off-chain audit of challenged data from storage providers. The Verifier Consortium will vote on the challenge results, and the failed outcomes will reduce the corresponding storage providers\u2019 staked BNB. Participants who submitted the challenge and the verifier received rewards for their involvement in this process. Data that failed to pass a challenge will not face another challenge for a specific time to allow storage providers to restore the data.

    Data challenger module will elaborate further on challenges associated with data availability.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/","title":"Underlying Storage Model - BNB Greenfield Data Storage","text":"

    An object on the Greenfield is stored among multi-SPs like below, for example, 50MB:

    We will introduce some concepts about data storage before describing in detail.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#segment","title":"Segment","text":"

    Segment is the basic storage unit of an object. An object payload is composed of one or many segments in sequence. The segment size is globally configured on the Greenfield blockchain. The default segment size is 16MB. For larger objects, the payload data will be broken into many segments. If the object\u2019s size is less than 16MB, it has only one segment and the segment size is the same as the object\u2019s size.

    Please note the payload data of an object will be split into the same size segment but the last segment, which is the actual size. For example, if one object has a size 50MB, only the size of the last segment is 2 MB and the other segments\u2019 sizes are all 16MB.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#ec-chunk","title":"EC Chunk","text":"

    Erasure Code (EC) is introduced to get efficient data redundancy on Greenfield. A segment is the boundary to perform erasure encoding. Some EC chunks are generated by erasure encoding one segment at a time. EC strategy is globally configured on the Greenfield blockchain. The default EC strategy is 4+2, 4 data chunks, and 2 parity chunks for one segment. The data chunk size is \u00bc of the segment. As one typical segment is 16M, one typical data chunk of EC is 4M.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#piece","title":"Piece","text":"

    Piece is the basic storage unit for backend storage on Greenfield. Each segment or EC chunk can be regarded as one data piece. And the key for each piece is generated based on the policy on the Greenfield chain.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#primary-sp","title":"Primary SP","text":"

    Each bucket on the Greenfield is bound with one SP, which is called primary SP. And the user needs to select an SP as the primary SP when creating a bucket. For all the objects stored under the bucket, primary SP will store one complete copy, all segments of the objects\u2019 payload data. And only the primary SP serves users\u2019 read or download requests.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#secondary-sp","title":"Secondary SP","text":"

    EC chunks of an object payload data are stored on some SPs, which are called secondary SPs. Each secondary SP stores part of payload data, which is used for better data availability. The object payload can be recovered from EC chunks.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#redundancy-strategy","title":"Redundancy Strategy","text":"

    Redundancy strategy defines how an object payload is stored among SPs, which is globally configured on the Greenfield blockchain. Below is the current strategy: * The data stream of the file will be split into segments according to the granularity of the segment size. If the size of the data is less than the segment size, it will be split according to the size of the data itself. The default segment size is 16MB; * Greenfield uses Reed-Solomon algorithm Reed-Solomon as its EC strategy, the default data blocks are 4, and the default parity blocks are 2 . * All the segment pieces of an object are stored on the Primary SP; * After EC encoding with the segment, the EC encoding module will generate six EC chunk pieces. All the EC chunk pieces of the segment will be stored to the six chosen secondary SPs.

    For example, when processing a 32MB file, the object is split into two segments. These two segments are stored in the primary storage provider, and each segment is encoded using erasure coding to generate six 4MB pieces. These six pieces are stored in six secondary storage providers in numerical order.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#integrity-hash","title":"Integrity Hash","text":"

    The integrity hashes include a root hash of the primary SP and several root hashes for each secondary SP which based on the EC strategy. The number of secondary hashes is equal dataBlocks plus parityBlock (it is six for now). Each piece\u2019s hash is computed by using hash algorithm (default is sha256) on the data piece\u2019s content. The pieces\u2019 root hash is computed based on all the pieces\u2019 hashes.

    The calculation process can be represented as follows:

    // secondaryHashN represents the Integrity Hash calculated by the Nth secondary SP.\n// segmentN_pieceN represents the Nth piece of the Nth segment of the object after EC encoding\nIntegrityHashes = [primaryHash, secondaryHash1 ...secondaryHash6]\nprimaryHash := hash(hash(segment1)+hash(segment2)..+hash(segmentN))\nsecondaryHashN := hash(hash(segment1_pieceN)+hash(segment2_pieceN)..+hash(segmentN_pieceN))\n
    For example, when processing a 32MB file, we got two segments called segment1 and segment2. The integrity hash of the primary SP is equal with hash(hash(segment1) + hash(segment2)). For each secondary SP, it stored piece1 and piece2 which is the encoding result by the segments. The integrity hash of the first secondary SP is equal with hash(hash(segment1_piece1) + hash(segment2_piece1)).

    Integrity hash is an important metadata of objects on the chain. During the process of creating an object, the integrity hash of each object is calculated and this information is recorded on the blockchain to ensure the accuracy of the data.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/","title":"Simple Storage Service - BNB Greenfield Data Storage","text":""},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#simple-storage-service","title":"Simple Storage Service","text":"

    Greenfield Simple Storage Service offers developers comparable API primitives and storage models to the AWS S3 cloud storage which is most utilized in Web2.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#features","title":"Features","text":""},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#storage-management","title":"Storage Management","text":"

    Greenfield has storage management features thart you can use to manage your resources, such as buckets, objects and groups. All the metadata of the resources are on-chain and can be only changed through transactions onto the greenfield blockchain.

    for more information, see Storage Module Design.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#permission-management","title":"Permission Management","text":"

    Greenfield Providers features for managing permissions to your buckets and objects. By default, Greenfield buckets and the objects in them are private. You only has the permissions to the resources you create. To grant granular resource permissions that support your specific use case of your resources, you can use the following features:

    for more information, see Permission Module Design.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#keys","title":"Keys","text":""},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#bucket","title":"Bucket","text":"

    In Greenfield, a bucket is a virtual container for storing objects. Users must assign each bucket a unique name that complies with DNS naming conventions, consisting of one or more labels separated by periods. It\u2019s crucial that the bucket name be globally unique within the Greenfield namespace to prevent two buckets from sharing the same name. Here are the bucket name rules for Greenfield:

    Once a bucket has been created, objects can be uploaded to it using various methods such as the gnfd command line or the SDKs. Objects within a bucket can be organized and managed like folders (also called \u201cprefixes\u201d). Additionally, it\u2019s possible to assign a unique key (a string value) to each object within the bucket to distinguish it from other objects.

    Every user account can create several buckets. The account will become the \u201cowner\u201d of the bucket.

    Each bucket should be associated with its own Primary SP, and the payment accounts for Read and Store functions. The owner\u2019s address will be the default payment account.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#object","title":"Object","text":"

    An object is a fundamental unit of storage in Greenfield, which represents a file consisting of data and its associated metadata. Each object is uniquely identified within a bucket by its object name (a string value). Here are the object name rules for Greenfield:

    While objects are commonly used to store files, they can contain any type of data, including text, images, videos, and program binaries.

    Users can upload objects to Greenfield using various methods, including the gnfd command line and SDKs. They can also download, copy, or move objects in a similar way.

    Objects in Greenfield have several important characteristics, including: - name and ID - owner - bucket that hosts it - size and timestamps - content type - checkSums for the storage pieces - storage status - associated SP information

    Object metadata is stored with the bucket name as the prefix of the key. It is possible to iterate through all objects under the same bucket, but it may be a heavy-lifting job for a large bucket with lots of objects.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#group","title":"Group","text":"

    A Group is a collection of accounts with the same permissions. Here are the group name rules for Greenfield:

    The group name is not allowed to be duplicated under the same user. However, a group can not create or own any resource. A group can not be a member of another group either.

    A resource can only have a limited number of groups associated with it for permissions. This ensures that the on-chain permission check can be finished within a constant time.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#group-member","title":"Group Member","text":"

    A Group Member is an account that is associated with a group. A group member can be added to multiple groups. Group Member has a expiration time which is set by the group owner. After the expiration time, the group member will still in the group, but the permission will be revoked.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#resource-based-policy","title":"Resource-Based Policy","text":"

    The user can use Resource-Based Policy to grant permissions to other accounts. Any resources, such as buckets, objects and groups, can associate several policy. Only the resource owner can put a policy which associate to a resource he owned.

    In the reousrce-based policy, the user can use wildcard characters Greenfield Resource Names(GRNS) and other values to grant permission to a subset of objects. For Example, the user can only allow the grantee to access to the objects that begin with a common prefix or end with a given extension, such as .html.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#life-cycle","title":"Life Cycle","text":"

    To store your data in Greenfield, the user should work with resources known as buckets and objects. A bucket is a container for objects, and an object is a file along with any metadata that describes that file.

    To store an object in Greenfield, the user creates a bucket and then uploads the object to that bucket. Once the object is in the bucket, it can be opened, downloaded, and moved. When the user no longer needs an object or a bucket, they can clean up their resources.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#bucket_1","title":"Bucket","text":""},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#object_1","title":"Object","text":""},{"location":"bnb-greenfield/for-developers/bundle-service/","title":"Bundle Service - BNB Greenfield Develop","text":"

    With more and more developers joining BNB Greenfield ecosystem, many good practices utilizing decentralized storage continue to emerge. On the other hand, sending small files to Greenfield is not an economic way. When small files are sent, the information about the files (metadata) saved in the system can be bigger than the files themselves. This means it costs more for both the users and Greenfield. For instance, imagine a user\u2019s account wants to uploads a website to Greenfield. If the files of the website are tiny but there are a lot of them, it leads to the same problem: too much metadata and higher costs.

    BNB Chain has proposed the core protocol for the Greenfield bundle to solve this problem. You can find more details about BEP-323. NodeReal is the first infrastructure provider to implement the bundling service. Bundling service provides a solution to combine small files together into one big file before sending it to Greenfield. Thus, developers can can cut down unnecessary costs while still get to each file in the big file as if they were separate.

    NodeReal Bundling service is fully open sourced, developers can use NodeReal bundle service directly, while they can also deploy their own bundle service if needed.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#bundle-format","title":"Bundle Format","text":"

    The bundle format specifies the structure and organization of the bundle that users create when packing files. This format is designed to pack flat files; hierarchical directory structures, or folders, are not supported.

    When dealing with a folder, we can simplify its structure by turning it into a series of individual files. As part of this process, we rename each file to include the folder path. For example, a file originally named file.txt inside the nested folders dira and dirb would be renamed to dira/dirb/file.txt. This approach allows us to maintain the organization of the folder while conforming to the requirement for flat files in the bundle.

    The bundle format is structured into several key components as follows:

    For more details, you can refer to the BEP-323 and Bundle-SDK.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#bundle-service","title":"Bundle Service","text":"

    With the bundle format above, users now can pack their small objects into a bundle and upload the bundle file to Greenfield. But users can not visit the objects in the bundle file conveniently.

    The bundle service is designed to serve the users or dApps uploading a lot of small objects to Greenfield and provide an indexing service for the objects in the bundle. Users can upload small objects to the bundle service and the bundle service will pack the small files into a bundle and upload it to Greenfield, at the same time, the bundle service will also provide a URL to visit each object in the bundle file.

    The bundle service will upload the bundle file to the bucket that the user specified, so the user should grant the account of the bundle service permission to upload files to the bucket. Meanwhile, the user should also grant the transaction fee for the bundle service to upload objects to Greenfield.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#architecture","title":"Architecture","text":"

    The bundle service contains two main components: API service and Bundler.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#api-service","title":"API Service","text":"

    The API service will serve users\u2019 requests like uploading an object, querying an object, etc.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#bundler","title":"Bundler","text":"

    The bundler will pack the objects that the user uploaded into a bundle file and upload it to a bucket in Greenfield.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#main-workflows","title":"Main Workflows","text":"

    It is important to understand that the Bundler service uploads bundled files to the user\u2019s bucket, the user has absolute control over the bundle files. This level of control allows users to manage and manipulate their bundled files as needed effectively.

    The bundle service utilizes its own account to send transactions and submit bundled files to Greenfield. Users are responsible for covering the transaction fees, and they need to grant authorization to the bundler account to create new files under their bucket. Therefore, it is essential to complete the necessary authorization before using the bundler service.

    Greenfield can manage permissions for buckets and files. However, to keep the bundler service streamlined, complex permission management is currently not available. The bundler service only supports public buckets, allowing only the bucket owner to upload files. However, all users can access the files through the bundler service with no authorization.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#grant-permission","title":"Grant Permission","text":""},{"location":"bnb-greenfield/for-developers/bundle-service/#upload-object","title":"Upload Object","text":"

    The bundle will be frozen if any of the following conditions are met: - The size of the bundle is equal to or greater than the MaxBundledSize, which has a default value of 1GB. - The number of objects in the current bundle is equal to or greater than the MaxBundledNumber, which has a default value of 1000. - The time interval since the creation of the bundle is equal to or greater than the MaxFinalizeTime, which has a default value of 24 hours.

    Users can also define their own rules for MaxBundledSize , MaxBundledNumber , and MaxFinalizeTime , but the values should not exceed the default ones.

    In this mode, when the previous bundle is frozen, if there are any new files uploaded, the bundler service will automatically create a new bundle for the user, eliminating the need for any additional user intervention. The bundles created by the bundler service follow the naming format of {bundle_prefix}_{bundle_nonce} . The bundle_prefix is bundle by default, and bundle_nonce is the number of bundles created in the bucket.

    In addition, users have the option to fully specify the lifecycle of a bundle by creating a new bundle using the \u201ccreate bundle\u201d API and then requesting to submit the bundle to Greenfield through the \u201cseal bundle\u201d API. It is important to note that the time from bundle creation to sealing should not exceed the DeaultMaxBundledTime of 24 hours. If this time limit is exceeded, the bundle service will automatically set the bundle as expired and the user can not finalize the bundle anymore.

    The bundler service is primarily designed to address the storage performance and efficiency issues associated with small files. Therefore, it is important to note that the file size uploaded to the bundle service should not exceed 16 MB. Any file exceeding this limit will be rejected by the bundle service.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#upload-bundle","title":"Upload Bundle","text":"

    Since users may want to upload files at the same time like uploading a website, the bundle service allows users to upload a valid bundle. You can use the bundle commandline tool to easily combine small objects into a bundle.

    The bundle service will validate the uploaded bundle, if the bundle is invalid, the request will be rejected.

    For the valid bundle, it will index all the files in the bundle so the user can visit the files in the bundle like the objects uploaded via UploadObject API.

    Unlike the UploadObject API, the user must specify the bundle name when uploading a bundle and the user are not allowed to upload objects to this bundle any longer. The bundle will be marked as Finalized and it will be uploaded to Greenfield by the bundle service.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#query-object","title":"Query Object","text":"

    The Bundle service stores index information for uploaded objects. It tracks the bundle and its metadata, making it easy to locate and index files bundled on Greenfield. The service also caches frequently accessed data to improve request performance. - When the bundler service has the file saved, the bundler service can respond to the request immediately. - If only the index information is available, the bundle service retrieves the file from Greenfield and returns it to the user. - If the index is missing, the service attempts to rebuild it from Greenfield and then retrieves and returns the file.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#apis","title":"APIs","text":"

    The Bundle Service Server API provides several endpoints for managing and interacting with bundles. Here\u2019s a brief overview:

    For more detailed information about each endpoint, including required parameters and response formats, please refer to the swagger.yaml file in https://github.com/node-real/greenfield-bundle-service.

    For detailed usage cases, you can refer to the e2e test cases in https://github.com/node-real/greenfield-bundle-service/tree/main/e2e.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#endpoints","title":"Endpoints","text":"

    Opensource implement from NodeReal

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#greenfield-testnet","title":"Greenfield Testnet","text":"

    Using the testnet\u2019s bundle service, the bundle file will be uploaded to the Greenfield testnet. Endpoint:

    https://gnfd-testnet-bundle.nodereal.io\n
    "},{"location":"bnb-greenfield/for-developers/bundle-service/#greenfield-mainnet","title":"Greenfield Mainnet","text":"

    Using the mainnet\u2019s bundle service, the bundle file will be uploaded to the Greenfield mainnet. Endpoint:

    https://gnfd-mainnet-bundle.nodereal.io\n
    "},{"location":"bnb-greenfield/for-developers/get-started-dev/","title":"Quick Guide - BNB Greenfield Develop","text":"

    Here\u2019s a quick guide to get you from zero to hero. This doc provides a guide to the following ideas:

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#greenfield-programmability-concepts","title":"Greenfield & Programmability Concepts","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#greenfield-101","title":"Greenfield 101","text":"

    Read Greenfield Overview here

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#uniform-address-format","title":"Uniform Address Format","text":"

    Greenfield defines its account in the same format as BSC and Ethereum. It starts with ECDSA secp256k1 curve for keys and is compliant with EIP84 for full BIP44 paths.

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#account-operation","title":"Account Operation","text":"

    Create a greenfield account, deposit BNB, and program token transfers.

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#data-storage","title":"Data storage","text":"

    Create a public bucket to upload and share objects.

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#permission-control","title":"Permission control","text":"

    Create a private bucket and share it with specific individuals.

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#enhanced-permission-control","title":"Enhanced permission control","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#cross-chain-programmability","title":"Cross-chain Programmability","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#developer-starter-kit","title":"Developer Starter Kit","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#api","title":"API","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#sdk","title":"SDK","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#setup","title":"Setup","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#developer-resource","title":"Developer Resource","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#storage-onramp","title":"Storage onramp","text":"

    https://dcellar.io/

    "},{"location":"bnb-greenfield/for-developers/interact-node/","title":"Interact with the Chain - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-developers/interact-node/#interact-with-the-chain","title":"Interact with the Chain","text":"

    There are multiple ways to interact with a node: using the CLI, using gRPC or using the REST endpoints.

    Info

    Since Greenfield Blockchain is based on Cosmos, The majority of the content in this page is copied from the Cosmos SDK.

    "},{"location":"bnb-greenfield/for-developers/interact-node/#using-the-cli","title":"Using the CLI","text":"

    Now that your chain is running, it is time to try sending tokens from the first account you created to a second account. In a new terminal window, start by running the following query command:

    gnfd query bank balances $MY_VALIDATOR_ADDRESS \n

    You should see the current balance of the account you created, equal to the original balance of BNB you granted it minus the amount you delegated via the gentx. Now, create a second account:

    gnfd keys add recipient --keyring-backend test\n\n# Put the generated address in a variable for later use.\nRECIPIENT=$(gnfd keys show recipient -a --keyring-backend test)\n

    The command above creates a local key-pair that is not yet registered on the chain. An account is created the first time it receives tokens from another account. Now, run the following command to send tokens to the recipient account:

    gnfd tx bank send $MY_VALIDATOR_ADDRESS $RECIPIENT 1000000BNB  --keyring-backend test\n\n# Check that the recipient account did receive the tokens.\ngnfd query bank balances $RECIPIENT \n
    "},{"location":"bnb-greenfield/for-developers/interact-node/#using-grpc","title":"Using gRPC","text":"

    The Protobuf ecosystem developed tools for different use cases, including code-generation from *.proto files into various languages. These tools allow the building of clients easily. Often, the client connection (i.e. the transport) can be plugged and replaced very easily.

    Since the code generation library largely depends on your own tech stack, we will only present three alternatives:

    "},{"location":"bnb-greenfield/for-developers/interact-node/#grpcurl","title":"grpcurl","text":"

    grpcurl is like curl but for gRPC. It is also available as a Go library, but we will use it only as a CLI command for debugging and testing purposes. Follow the instructions in the previous link to install it.

    Assuming you have a local node running (either a localnet, or connected a live network), you should be able to run the following command to list the Protobuf services available (you can replace localhost:9000 by the gRPC server endpoint of another node, which is configured under the grpc.address field inside app.toml:

    grpcurl -plaintext localhost:9090 list\n

    You should see a list of gRPC services, like cosmos.bank.v1beta1.Query. This is called reflection, which is a Protobuf endpoint returning a description of all available endpoints. Each of these represents a different Protobuf service, and each service exposes multiple RPC methods you can query against.

    In order to get a description of the service you can run the following command:

    grpcurl \\\n    localhost:9090 \\\n    describe cosmos.bank.v1beta1.Query                  # Service we want to inspect\n

    It\u2019s also possible to execute an RPC call to query the node for information:

    grpcurl \\\n    -plaintext\n    -d '{\"address\":\"$MY_VALIDATOR\"}' \\\n    localhost:9090 \\\n    cosmos.bank.v1beta1.Query/AllBalances\n
    "},{"location":"bnb-greenfield/for-developers/interact-node/#query-for-historical-state-using-grpcurl","title":"Query for historical state using grpcurl","text":"

    You may also query for historical data by passing some gRPC metadata to the query: the x-cosmos-block-height metadata should contain the block to query. Using grpcurl as above, the command looks like:

    grpcurl \\\n    -plaintext \\\n    -H \"x-cosmos-block-height: 279256\" \\\n    -d '{\"address\":\"$MY_VALIDATOR\"}' \\\n    localhost:9090 \\\n    cosmos.bank.v1beta1.Query/AllBalances\n

    Assuming the state at that block has not yet been pruned by the node, this query should return a non-empty response.

    "},{"location":"bnb-greenfield/for-developers/interact-node/#programmatically-via-go","title":"Programmatically via Go","text":"

    The following snippet shows how to query the state using gRPC inside a Go program. The idea is to create a gRPC connection, and use the Protobuf-generated client code to query the gRPC server.

    "},{"location":"bnb-greenfield/for-developers/interact-node/#install-greenfield-go-sdk","title":"Install Greenfield GO-sdk","text":"

    Refer to Go-sdk doc to install the latest dependency.

    Init client without key manager, you should use it for only querying purpose.

    client := NewGreenfieldClient(\"localhost:9090\", \"greenfield_9000-121\")\n\nquery := banktypes.QueryBalanceRequest{\n    Address: \"0x76d244CE05c3De4BbC6fDd7F56379B145709ade9\",\n    Denom:   \"BNB\",\n}\nres, err := client.BankQueryClient.Balance(context.Background(), &query)  \n

    Init client with key manager, for signing and sending tx

    keyManager, _ := keys.NewPrivateKeyManager(\"ab463aca3d2965233da3d1d6108aa521274c5ddc2369ff72970a52a451863fbf\")\ngnfdClient := NewGreenfieldClient(\"localhost:9090\", \n                                \"greenfield_9000-121\",\n                                WithKeyManager(km),\n                                    WithGrpcDialOption(grpc.WithTransportCredentials(insecure.NewCredentials()))\n)\n
    "},{"location":"bnb-greenfield/for-developers/interact-node/#using-the-rest-endpoints","title":"Using the REST Endpoints","text":"

    As described in the gRPC guide, all gRPC services on the Cosmos SDK are made available for more convenient REST-based queries. The format of the URL path is based on the Protobuf service method\u2019s full-qualified name, but may contain small customizations so that final URLs look more idiomatic. For example, the REST endpoint for the cosmos.bank.v1beta1.Query/AllBalances method is GET /cosmos/bank/v1beta1/balances/{address}. Request arguments are passed as query parameters.

    As a concrete example, the curl command to make balances request is:

    curl \\\n    -X GET \\\n    -H \"Content-Type: application/json\" \\\n    http://localhost:1317/cosmos/bank/v1beta1/balances/$MY_VALIDATOR\n

    Make sure to replace localhost:1317 with the REST endpoint of your node, configured under the api.address field.

    The list of all available REST endpoints is available as a Swagger specification file, it can be viewed at localhost:1317/swagger. Make sure that the api.swagger field is set to true in your app.toml.

    "},{"location":"bnb-greenfield/for-developers/interact-node/#query-for-historical-state-using-rest","title":"Query for historical state using REST","text":"

    Querying for historical state is done using the HTTP header x-cosmos-block-height. For example, a curl command would look like:

    curl \\\n    -X GET \\\n    -H \"Content-Type: application/json\" \\\n    -H \"x-cosmos-block-height: 279256\"\n    http://localhost:1317/cosmos/bank/v1beta1/balances/$MY_VALIDATOR\n

    Assuming the state at that block has not yet been pruned by the node, this query should return a non-empty response.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/","title":"APIs and SDKs - BNB Greenfield API and SDK","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/#apis-sdks","title":"APIs & SDKs","text":"

    Below are the lists of Official APIs and SDKs for BNB Greenfield in different languages.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/#official-apis","title":"Official APIs","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/#official-sdks","title":"Official SDKs","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/","title":"Go SDK Example - BNB Greenfield SDK","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#quickstart","title":"Quickstart","text":"

    The Greenfield SDK for Go provides APIs and utilities that developers can use to build Go applications that use Greenfield services, such as data storage and permission management.

    The SDK simplifies the process of programming directly with a web service interface. It takes care of many underlying details, including authentication, retrying requests, and managing errors.

    This guide provides configuration information, sample code, and an introduction to the SDK utilities.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#install","title":"Install","text":"

    The Greenfield SDK for Go requires Go 1.20 or later.You can view your current version of Go by running the go version command. For information about installing or upgrading your version of Go, see https://golang.org/doc/install.

    To install the SDK and its dependencies, run the following Go command.

    $ go get github.com/bnb-chain/greenfield-go-sdk\n

    Edit go.mod to replace dependencies

    replace (\n    cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9\n    cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9\n    github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2\n    github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1\n    github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3\n    github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1\n    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7\n)\n

    Install dependensies

    go mod tidy\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#usage","title":"Usage","text":"

    Now we\u2019re ready to connect to Greenfield testnet and interact with the Greenfield APIs. Let\u2019s write a simple script to query the Greenfield version to verify if everything works as expected.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#create-client","title":"Create client","text":"

    Create a main.go file in your project and add the following code.

    package main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/bnb-chain/greenfield-go-sdk/client\"\n    \"github.com/bnb-chain/greenfield-go-sdk/types\"\n)\n\nconst (\n    privateKey  = \"\"\n\n    // Mainnet Info\n    rpcAddr     = \"https://greenfield-chain.bnbchain.org:443\"\n    chainId     = \"greenfield_1017-1\"\n\n    // Testnet Info\n    // rpcAddr     = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n    // chainId     = \"greenfield_5600-1\"\n\n)\n\nfunc main() {\n    // import acccount\n    account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n    if err != nil {\n        log.Fatalf(\"New account from private key error, %v\", err)\n    }\n\n    // create client\n    cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n    }\n    ctx := context.Background()\n\n    // get node info from RPC\n    nodeInfo, versionInfo, err := cli.GetNodeInfo(ctx)\n    if err != nil {\n        log.Fatalf(\"unable to get node info, %v\", err)\n    }\n    log.Printf(\"nodeInfo moniker: %s, go version: %s\", nodeInfo.Moniker, versionInfo.GoVersion)\n\n    // query latest block height\n    height, err := cli.GetLatestBlockHeight(ctx)\n    if err != nil {\n        log.Fatalf(\"unable to get latest block height, %v\", err)\n    }\n\n    log.Printf(\"Current block height: %d\", height)\n}\n

    Run the following command in your project directory:

    go run main.go\n

    This will output something like:

    2023/06/22 10:44:16 nodeInfo moniker: validator-a, go version: go version go1.20.4 linux/amd64\n2023/06/22 10:44:16 Current block height: 817082\n

    If everything is set up correctly, your code will be able to connect to the Greenfield node and return the chain data as shown above.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#queries","title":"Queries","text":"

    In the previous step, we created a main.go file to demonstrate the basic steps to connect to the node and initialize a Client to query chain data. Next, let\u2019s use some more functions.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#1-get-current-chain-head","title":"1. Get Current Chain Head","text":"

    We can add the following code inmain.goto query current head of the chain.

      // query latest block height\n  blockByHeight, err := cli.GetBlockByHeight(ctx,height)\n    if err != nil {\n        log.Fatalf(\"unable to get block by height, %v\", err)\n    }\n    log.Printf(\"Current block height: %d\", blockByHeight.GetHeader())\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#2-get-address-balance","title":"2. Get Address Balance","text":"

    With a given greenfield wallet address, you can query its balance by calling GetAccountBalance function.

        // query current balance\n    balance, err := cli.GetAccountBalance(ctx, account.GetAddress().String())\n    if err != nil {\n        log.Fatalf(\"unable to get balance, %v\", err)\n    }\n    log.Printf(\"%s Current balance: %s\", account.GetAddress().String(), balance.String())\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#3-query-storage-providers","title":"3. Query Storage Providers","text":"

    In addition, the SDK provides support for querying the list of storage providers available and offers generic search capabilities for exploring metadata attributes.

        cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n    }\n    ctx := context.Background()\n\n    // get storage providers list\n    spLists, err := cli.ListStorageProviders(ctx, true)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n    }\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#4-query-storage-price","title":"4. Query Storage Price","text":"
        // choose the first sp to be the primary SP\n    primarySP := spLists[0].GetOperatorAddress()\n\n    // query price for storing data\n    price, err := cli.GetStoragePrice(ctx,primarySP)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n    }\n\n    log.Printf(\"Read Price is %s and Store price is %s \\n\",price.ReadPrice,price.StorePrice)\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#5-query-buckets","title":"5. Query Buckets","text":"

    You can query the bucket info like this:

        // head bucket\n    bucketInfo, err := cli.HeadBucket(ctx, bucketName)\n    handleErr(err, \"HeadBucket\")\n    log.Println(\"bucket info:\", bucketInfo.String())\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#5-query-objects","title":"5. Query Objects","text":"

    List all the objects under the same bucket

        // list object\n    objects, err := cli.ListObjects(ctx, bucketName, types.ListObjectsOptions{\n        ShowRemovedObject: false, Delimiter: \"\", MaxKeys: 100, EndPointOptions: &types.EndPointOptions{\n            Endpoint:  httpsAddr, // sp endpoint\n            SPAddress: \"\",\n        }})\n    log.Println(\"list objects result:\")\n    for _, obj := range objects.Objects {\n        i := obj.ObjectInfo\n        log.Printf(\"object: %s, status: %s\\n\", i.ObjectName, i.ObjectStatus)\n    }\n

    Apart from the basic data queries shown above, there are many more features. Please see theJSON-RPC API Referencefor all Greenfield API definitions.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#transactions","title":"Transactions","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#1-manage-wallet","title":"1. Manage Wallet","text":"

    Greenfield wallets hold addresses that you can use to manage objects, sign transactions, and pay for gas fees. In this section, we will demonstrate different ways to manage your wallet.

        //import mnemonic\n    account, err := types.NewAccountFromMnemonic(\"test\", mnemonic)\n    //import private key\n    account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n

    Let\u2019s create a second wallet address so we can test transfers. The new address will be created locally and start with 0 token balance:

        //create a differet account\n    account2, _, err := types.NewAccount(\"test2\")\n

    Now, let\u2019s try to transfer tBNB to this new address. Under the hood, this will create a transaction to transfer tBNB fromfromAddresstotoAddress, sign the transaction using SDK, and send the signed transaction to the Greenfield node.

        // transfer token to acccount2\n    transferTxHash, err := cli.Transfer(ctx, account2.GetAddress().String(), math.NewIntFromUint64(1000000000000000000), types2.TxOption{})\n    if err != nil {\n        log.Fatalf(\"unable to send, %v\", err)\n    }\n    log.Printf(\"Transfer response: %s\", transferTxHash)\n\n    // wait for transaction hash\n    waitForTx, err := cli.WaitForTx(ctx, transferTxHash)\n\n    log.Printf(\"Wait for tx: %s\", waitForTx.String())\n\n    //verify account2's balance\n    balance, err = cli.GetAccountBalance(ctx, account2.GetAddress().String())\n

    Run the code to test the transfer of tBNB:

        go run account.go\n

    This will output something like:

    raw_log: '[{\"msg_index\":0,\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"/cosmos.bank.v1beta1.MsgSend\"},{\"key\":\"sender\",\"value\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"coin_spent\",\"attributes\":[{\"key\":\"spender\",\"value\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"},{\"key\":\"amount\",\"value\":\"1BNB\"}]},{\"type\":\"coin_received\",\"attributes\":[{\"key\":\"receiver\",\"value\":\"0x78C3A3d10B1032bB2810366361dCE84E2e92eFCB\"},{\"key\":\"amount\",\"value\":\"1BNB\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"0x78C3A3d10B1032bB2810366361dCE84E2e92eFCB\"},{\"key\":\"sender\",\"value\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"},{\"key\":\"amount\",\"value\":\"1BNB\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"}]}]}]'\ntimestamp: \"2023-06-22T20:02:19Z\"\ntx:\n  '@type': /cosmos.tx.v1beta1.Tx\n  auth_info:\n    fee:\n      amount:\n      - amount: \"6000000000000\"\n        denom: BNB\n      gas_limit: \"1200\"\n      granter: \"\"\n      payer: \"\"\n    signer_infos:\n    - mode_info:\n        single:\n          mode: SIGN_MODE_EIP_712\n      public_key:\n        '@type': /cosmos.crypto.eth.ethsecp256k1.PubKey\n        key: AirjhHwjRcZ34op5yCKHtDkn91RDgFOY8cJmbHH6Tmlu\n      sequence: \"12\"\n    tip: null\n  body:\n    extension_options: []\n    memo: \"\"\n    messages:\n    - '@type': /cosmos.bank.v1beta1.MsgSend\n      amount:\n      - amount: \"1\"\n        denom: BNB\n      from_address: 0x525482AB3922230e4D73079890dC905dCc3D37cd\n      to_address: 0x78C3A3d10B1032bB2810366361dCE84E2e92eFCB\n    non_critical_extension_options: []\n    timeout_height: \"0\"\n  signatures:\n  - FjUNT2dzpQZhCmVTLDGMEy1uR1NaNLeYjvqQiPr2xHM5xxeYP5Mic8CSxZtg3k4WHcAIEnQNcszqBi7fsgETagA=\ntxhash: DFC2CE0514FE334B5BCB6BC3EBCCCD7A6E16B4CAEDC4FFDBE3F2FA3B6E548E61\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#make-a-storage-deal","title":"Make A Storage Deal","text":"

    Storing data is one of the most important features of Greenfield. In this section, we\u2019ll walk through the end-to-end process of storing your data on the Greenfield network. We\u2019ll start by importing your data, then make a storage deal with a storage provider, and finally wait for the deal to complete.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#1-create-a-storagego-file","title":"1. Create a storage.go file","text":"

    Create a storage.go file in yourdemoproject and add the following boilerplate code:

    func main() {\n\n  // initialize account\n  account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n  log.Println(\"address info:\", account)\n\n  if err != nil {\n      log.Fatalf(\"New account from private key error, %v\", err)\n  }\n\n  //initialize client\n  cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n  if err != nil {\n      log.Fatalf(\"unable to new greenfield client, %v\", err)\n  }\n  ctx := context.Background()\n\n  // 1. choose storage provider\n\n  // 2. Create a bucket\n\n  // 3. Upload your data and set a quota\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#2-choose-sp","title":"2. Choose SP","text":"

    You can query the list of SP.

        // get storage providers list\n    spLists, err := cli.ListStorageProviders(ctx, true)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n    }\n    //choose the first sp to be the primary SP\n    primarySP := spLists[0].GetOperatorAddress()\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#3-create-buckets","title":"3. Create Buckets","text":"

    Bucket can be private or public. You can customize it with options.

        chargedQuota := uint64(100)\n    visibility := storageTypes.VISIBILITY_TYPE_PUBLIC_READ\n    opts := types.CreateBucketOptions{Visibility: visibility, ChargedQuota: chargedQuota}\n

    To understand how does quota work, read this.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#4-upload-objects","title":"4. Upload Objects","text":"

    Objects can also be private or public.

    Uploading objects is composed of two parts: create and put.

        // create and put object\n    txnHash, err := cli.CreateObject(ctx, bucketName, objectName, bytes.NewReader(buffer.Bytes()), types.CreateObjectOptions{})\n\n    handleErr(err, \"CreateObject\")\n\n    // Put your object\n    err = cli.PutObject(ctx, bucketName, objectName, int64(buffer.Len()),\n        bytes.NewReader(buffer.Bytes()), types.PutObjectOptions{TxnHash: txnHash})\n    handleErr(err, \"PutObject\")\n\n    log.Printf(\"object: %s has been uploaded to SP\\n\", objectName)\n\n    //wait for SP to seal your object\n    waitObjectSeal(cli, bucketName, objectName)\n

    The primary SP syncs with secondary SPs to set up the data redundancy, and then it signs a \u201cSeal\u201d transaction with the finalized metadata for storage. If the primary SP determines that it doesn\u2019t want to store the file due to whatever reason, it can also \u201cSealReject\u201d the request.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#object-management","title":"Object Management","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#1-read-object","title":"1. Read Object","text":"

    You can call GetObject function to download data.

        // get object\n    reader, info, err := cli.GetObject(ctx, bucketName, objectName, types.GetObjectOption{})\n    handleErr(err, \"GetObject\")\n    log.Printf(\"get object %s successfully, size %d \\n\", info.ObjectName, info.Size)\n    handleErr(err, \"GetObject\")\n    objectBytes, err := io.ReadAll(reader)\n    if !bytes.Equal(objectBytes, buffer.Bytes()) {\n        handleErr(errors.New(\"download content not same\"), \"GetObject\")\n    }\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#2-update-object-visibility","title":"2. Update Object Visibility","text":"

    You can call UpdateObjectVisibility to change object visibility

        // update object visibility\n    updateBucketTx, err := ccli.UpdateBucketVisibility(s.ClientContext, bucketName,\n    storageTypes.VISIBILITY_TYPE_PRIVATE, types.UpdateVisibilityOption{})\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#3-delete-object","title":"3. Delete Object","text":"

    The function DeleteObject support deleting objects.

        // delete object\n    delTx, err := cli.DeleteObject(ctx, bucketName, objectName, types.DeleteObjectOption{})\n    handleErr(err, \"DeleteObject\")\n    _, err = cli.WaitForTx(ctx, delTx)\n    if err != nil {\n        log.Fatalln(\"txn fail\")\n    }\n    log.Printf(\"object: %s has been deleted\\n\", objectName)\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#greenfield-client-documentation","title":"Greenfield Client Documentation","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#usage_1","title":"Usage","text":"

    Import Greenfield Go SDK client package, client package provides a client for interacting with Greenfield blockchain and SPs.

        import \"github.com/bnb-chain/greenfield-go-sdk/client\"\n

    Provide Greenfield blockchain RPC endpoint and chainID info, new a Greenfield Go SDK client instance to start the journey.

    func New(chainID string, endpoint string, option Option) (Client, error)\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#api-documentation","title":"API Documentation","text":"

    The Greenfield Go SDK client wraps lots of APIs for interacting with Greenfield, including account, bank, storage, and permission APIs, etc. For more details, you can refer to Greenfield Go SDK Docs.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#code-repository","title":"Code Repository","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#more-info","title":"More info","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/","title":"Javascript SDK Example - BNB Greenfield SDK","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#quickstart","title":"Quickstart","text":"

    The BNB Greenfield JavaScript SDK is designed for front-end environments and provides an API for interacting with BNB Greenfield decentralized storage. It offers a range of operations, including retrieving permission details, gas fees, etc. The SDK also includes a crypto component for signing transactions and sending them to BNB Greenfield.

    However, it should be noted that this SDK does not include methods for interacting with BNB Smart Chain (BSC). For a comprehensive understanding of available operations, refer to the API Reference.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#install","title":"Install","text":"
    npm install @bnb-chain/greenfield-js-sdk\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#usage","title":"Usage","text":"

    To utilize the SDK functionality, users need to instantiate a client object from the SDK. This client object serves as the interface to interact with BNB Greenfield and perform the desired operations.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#create-client","title":"Create client","text":"
    import { Client } from '@bnb-chain/greenfield-js-sdk'\n\nexport const client = Client.create('https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org', '5600');\n

    The SDK offers two types of operations - sending transactions to BNB Greenfield, allowing users to modify the state of the blockchain; the second type enables users to send queries and retrieve metadata information about objects stored on the blockchain.

    The SDK consists of two parts:

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#transactions","title":"Transactions","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#1-transaction-construction","title":"1. Transaction construction","text":"

    The SDK offers functionality for transferring tokens between accounts, providing a straightforward and convenient way to perform token transfers. With the SDK, users can easily initiate and execute token transfers within the desired accounts, streamlining the process of managing and exchanging tokens.

    The SDK includes functionality for simulating and broadcasting transactions, allowing users to retrieve essential information related to gas fees, and sending the transaction over network.

    const { simulate, broadcast } = await client.account.transfer({\n  fromAddress: address,\n  toAddress: transferInfo.to,\n  amount: [\n    {\n      denom: 'BNB',\n      amount: ethers.utils.parseEther(transferInfo.amount).toString(),\n    },\n  ],\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#2-simulate-transactions","title":"2. Simulate Transactions","text":"

    This function returns the estimated gas limit, gas price, and overall gas fee.

    // simulate tx\nconst simulateInfo = await simulate({\n   denom: 'BNB',\n});\n

    Example output

    {\n   \"gasLimit\":2400,\n   \"gasPrice\":\"5000000000\",\n   \"gasFee\":\"0.000012\"\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#3-broadcast-transactions","title":"3. Broadcast Transactions","text":"

    Use the API endpoint to send the transaction data to the blockchain network.

    // broadcast tx\n// This includes details such as gas limit, gas price, and overall gas fee.\nconst broadcastRes = await broadcast({\n  denom: 'BNB',\n  gasLimit: Number(simulateInfo.gasLimit),\n  gasPrice: simulateInfo.gasPrice,\n  payer: address,\n  granter: '',\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#notice-signature-mode-for-broadcast","title":"NOTICE: Signature mode for Broadcast","text":"

    broadcast use window.ethereum as signature provider by default.

    If you want to use others, you can set signTypedDataCallback:

    // TrustWallet\nconst broadcastRes = await broadcast({\n  //...\n  signTypedDataCallback: async (addr: string, message: string) => {\n    return await window.trustwallet.request({\n      method: 'eth_signTypedData_v4',\n      params: [addr, message],\n    });\n  }\n});\n

    If you broadcast in Nodejs, you can broadcast a tx by privateKey:

    const broadcastRes = await broadcast({\n  //...\n  privateKey: '0x.......'\n});\n

    Example output after broadcast your transaction:

    transaction result
    {\n   \"code\":0,\n   \"height\":449276,\n   \"txIndex\":0,\n   \"events\":[\n      {\n         \"type\":\"coin_spent\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"coin_received\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"transfer\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"message\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"tx\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"tx\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"tx\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"message\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"coin_spent\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"coin_received\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"transfer\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"message\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"greenfield.payment.EventStreamRecordUpdate\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"greenfield.payment.EventStreamRecordUpdate\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"greenfield.payment.EventStreamRecordUpdate\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"greenfield.storage.EventCreateBucket\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      }\n   ],\n   \"rawLog\":\"..\",\n   \"transactionHash\":\"D304242145ED9B44F05431C3798B3273CF2A907E6AE1CA892759985C900D6E72\",\n   \"gasUsed\":2400,\n   \"gasWanted\":2400\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#4-multi-transactions","title":"4. Multi-Transactions","text":"

    The SDK also provides support for bundling multiple operations into a single transaction, thereby reducing gas fees. This feature allows users to optimize their transactions by combining several operations together, minimizing the overall gas cost associated with executing them individually. By leveraging this functionality, users can effectively manage their gas fees and enhance the efficiency of their transactions within the blockchain network using the SDK.

    const createGroupTx = await client.group.createGroup(params);\nconst mirrorGroupTx = await client.crosschain.mirrorGroup({\n   groupName,\n   id,\n   operator,\n});\n\nconst principal = {\n  type: PermissionTypes.PrincipalType.PRINCIPAL_TYPE_GNFD_GROUP,\n  value: GRNToString(newGroupGRN(address as string, groupName)),\n};\n\nconst statement: PermissionTypes.Statement = {\n  effect: PermissionTypes.Effect.EFFECT_ALLOW,\n  actions: [PermissionTypes.ActionType.ACTION_GET_OBJECT],\n  resources: [\n    GRNToString(\n      type === 'Data'\n        ? newObjectGRN(bucketName, name)\n        : newObjectGRN(bucketName, '*'),\n    ),\n  ],\n};\n\nconst policyTx = await client.object.putObjectPolicy(bucketName, name, {\n  operator: address,\n  statements: [statement],\n  principal,\n});\n\nconst { simulate, broadcast } = await multiTx([\n  createGroupTx,\n  mirrorGroupTx,\n  policyTx,\n]);\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#querying-metadata","title":"Querying Metadata","text":"
    const { client, selectSp, generateString } = require('./client');\nconst { ACCOUNT_ADDRESS, ACCOUNT_PRIVATEKEY } = require('./env');\nconst Long = require('long');\n\n(async () => {\n  // get account info\n  const addrInfo = await client.account.getAccount(ACCOUNT_ADDRESS);\n\n  console.log('address is', addrInfo);\n\n\n})\n

    Example output

    {\n   \"address\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\",\n   \"pubKey\":{\n      \"typeUrl\":\"/cosmos.crypto.eth.ethsecp256k1.PubKey\",\n      \"value\":\"CiECKuOEfCNFxnfiinnIIoe0OSf3VEOAU5jxwmZscfpOaW4=\"\n   },\n   \"accountNumber\":\"5012\",\n   \"sequence\":\"9\"\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#storage-provider-client","title":"Storage Provider Client","text":"

    https://github.com/bnb-chain/greenfield-storage-provider/tree/master/docs/storage-provider-rest-api

    In addition, the SDK provides support for querying the list of storage providers available and offers generic search capabilities for exploring metadata attributes.

    SDK support two authentication type:

    getBucketReadQuota as example:

    // generate seed:\nconst allSps = await getAllSps();\nconst offchainAuthRes = await client.offchainauth.genOffChainAuthKeyPairAndUpload(\n  {\n    sps: allSps,\n    chainId: GREEN_CHAIN_ID,\n    expirationMs: 5 * 24 * 60 * 60 * 1000,\n    domain: window.location.origin,\n    address: 'your address',\n  },\n  provider: 'wallet provider',\n);\n\n// request sp api\nconst bucketQuota = await client.bucket.getBucketReadQuota(\n  {\n    bucketName,\n  },\n  {\n    type: 'EDDSA',\n    seed: offchainAuthRes.seedString,\n    domain: window.location.origin,\n    address: 'your address',\n  },\n);\n
    // Node.js:\n// request sp api\nconst bucketQuota = await client.bucket.getBucketReadQuota(\n  {\n    bucketName,\n  },\n  {\n    type: 'ECDSA',\n    privateKey: '0x....'\n  },\n);\n

    Others functions:

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#list-storage-providers","title":"List Storage Providers","text":"
    export const getSps = async () => {\n  const sps = await client.sp.getStorageProviders();\n  const finalSps = (sps ?? []).filter(\n    (v: any) => v?.description?.moniker !== 'QATest',\n  );\n\n  return finalSps;\n};\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#search-for-objects","title":"Search for objects","text":"

    It\u2019s important to note that even if an object is set to private, its metadata remains publicly accessible. This metadata includes information such as file size, file type, and file name.

    export const searchKey = async (key: string) => {\n  try {\n    return await client.sp.listGroup(key, `${DAPP_NAME}_`, {\n      sourceType: 'SOURCE_TYPE_ORIGIN',\n      limit: 1000,\n      offset: 0,\n    });\n  } catch (e) {\n    return [];\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#examples","title":"Examples","text":"

    Now let\u2019s make a complete example, includes:

    1. create bucket
    2. create object and upload it to the bucket
    3. download the object
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#prepare","title":"Prepare","text":"

    To begin, create an account and deposit tokens into it on Greenfield. Follow the instructions provided in Token Transfer. Please be aware that if your account does not have any BNB, the transaction will not be executed.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#choose-storage-provider","title":"Choose Storage Provider","text":"

    Storing data is one of the most important features of Greenfield. All storage-related apis require the storage provider to be chose.

    select sp
    const spList = await client.sp.getStorageProviders();\nconst sp = {\n   operatorAddress: spList[0].operatorAddress,\n   endpoint: spList[0].endpoint,\n};\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#ecdsa-offchainauth","title":"ECDSA / OffChainAuth","text":"

    ECDSA require users to use private key for authentication.

    OffChainAuth is used to authenticate yourself to the provider.

    Code can\u2019t access user\u2019s private key on browser, so we use OffChainAuth on browser and use ECDSA on Nodejs.

    BrowserNodejs Browser
    // MetaMask\nconst provider = window.ethereum;\n\nconst offchainAuthRes = await client.offchainauth.genOffChainAuthKeyPairAndUpload({\n   sps: {\n      address: sp.operatorAddress,\n      endpoint: sp.endpoint,\n   },\n   chainId: '5600',\n   expirationMs: 5 * 24 * 60 * 60 * 1000,\n   domain: window.location.origin,\n   // your wallet account\n   address: '0x..',\n}, provider);\n

    Info

    Nodejs don\u2019t need offchainauth.

    Nodejs
    // your account\nconst ACCOUNT_ADDRESS = '0x....'\n\n// your account's private key\nconst ACCOUNT_PRIVATEKEY = '0x....'\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#1-create-bucket","title":"1. Create Bucket","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#11-construct-create-bucket-tx","title":"1.1 construct create bucket tx","text":"

    Bucket can be private or public, you can customize it with options (visibility):

    construct create bucket tx
    const createBucketTx = await client.bucket.createBucket(\n  {\n    bucketName: 'bucket_name',\n    creator: address,\n    visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,\n    chargedReadQuota: Long.fromString('0'),\n    primarySpAddress: sp.operatorAddress,\n    paymentAddress: address,\n  }\n);\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#12-simulate-create-bucket-tx","title":"1.2 simulate create bucket tx","text":"simulate create bucket tx
    const createBucketTxSimulateInfo = await createBucketTx.simulate({\n   denom: 'BNB',\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#13-broadcast-create-bucket-tx","title":"1.3 broadcast create bucket tx","text":"BrowserNodejs broadcast create bucket tx
    const res = await createBucketTx.broadcast({\n   denom: 'BNB',\n   gasLimit: Number(simulateInfo?.gasLimit),\n   gasPrice: simulateInfo?.gasPrice || '5000000000',\n   payer: address,\n   granter: '',\n});\n
    broadcast create bucket tx
    const res = await createBucketTx.broadcast({\n   denom: 'BNB',\n   gasLimit: Number(createBucketTxSimulateInfo?.gasLimit),\n   gasPrice: createBucketTxSimulateInfo?.gasPrice || '5000000000',\n   payer: ACCOUNT_ADDRESS,\n   granter: '',\n   // highlight-start\n   privateKey: ACCOUNT_PRIVATEKEY,\n   // highlight-end\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#2-create-object","title":"2. Create Object","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#21-construct-create-object-tx","title":"2.1 construct create object tx","text":"

    Like the visibility of bucket, object also has a visibility:

    Getting file\u2019s checksum need reed-solomon:

    BrowserNodejs
    import { ReedSolomon } from '@bnb-chain/reed-solomon';\n\nconst rs = new ReedSolomon();\n\n// file is File type\nconst fileBytes = await file.arrayBuffer();\nconst expectCheckSums = rs.encode(new Uint8Array(fileBytes));\n
    const fs = require('node:fs');\nconst { NodeAdapterReedSolomon } = require('@bnb-chain/reed-solomon/node.adapter');\n\nconst filePath = './CHANGELOG.md';\nconst fileBuffer = fs.readFileSync(filePath);\nconst rs = new NodeAdapterReedSolomon();\nconst expectCheckSums = await rs.encodeInWorker(__filename, Uint8Array.from(fileBuffer));\n
    const createObjectTx = await client.object.createObject(\n  {\n    bucketName: 'bucket_name',\n    objectName: 'object_name',\n    // user's account address\n    creator: '0x...',\n    visibility: VisibilityType.VISIBILITY_TYPE_PRIVATE,\n    contentType: 'json',\n    redundancyType: RedundancyType.REDUNDANCY_EC_TYPE,\n    payloadSize: Long.fromInt(13311),\n    expectChecksums: expectCheckSums.map((x) => bytesFromBase64(x)),\n  }\n);\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#22-simulate-create-object-tx","title":"2.2 simulate create object tx","text":"
    const createObjectTxSimulateInfo = await createObjectTx.simulate({\n   denom: 'BNB',\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#23-broadcast-create-object-tx","title":"2.3 broadcast create object tx","text":"BrowserNodejs
    const res = await createObjectTx.broadcast({\n   denom: 'BNB',\n   gasLimit: Number(simulateInfo?.gasLimit),\n   gasPrice: simulateInfo?.gasPrice || '5000000000',\n   payer: address,\n   granter: '',\n});\n
    const createObjectTxRes = await createObjectTx.broadcast({\n   denom: 'BNB',\n   gasLimit: Number(createObjectTxSimulateInfo?.gasLimit),\n   gasPrice: createObjectTxSimulateInfo?.gasPrice || '5000000000',\n   payer: ACCOUNT_ADDRESS,\n   granter: '',\n   // highlight-start\n   privateKey: ACCOUNT_PRIVATEKEY,\n   // highlight-end\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#24-upload-object","title":"2.4 upload object","text":"BrowserNodejs
    const uploadRes = await client.object.uploadObject(\n   {\n      bucketName: createObjectInfo.bucketName,\n      objectName: createObjectInfo.objectName,\n      body: file,\n      txnHash: txHash,\n   },\n   // highlight-start\n   {\n      type: 'EDDSA',\n      domain: window.location.origin,\n      seed: offChainData.seedString,\n      address,\n   },\n   // highlight-end\n);\n
    const uploadRes = await client.object.uploadObject(\n   {\n      bucketName: bucketName,\n      objectName: objectName,\n      body: createFile(filePath),\n      txnHash: createObjectTxRes.transactionHash,\n   },\n   // highlight-start\n   {\n      type: 'ECDSA',\n      privateKey: ACCOUNT_PRIVATEKEY,\n   }\n   // highlight-end\n);\n\n// convert buffer to file\nfunction createFile(path) {\n  const stats = fs.statSync(path);\n  const fileSize = stats.size;\n\n  return {\n    name: path,\n    type: '',\n    size: fileSize,\n    content: fs.readFileSync(path),\n  }\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#3-download-object","title":"3. Download Object","text":"BrowserNodejs
    const res = await client.object.downloadFile(\n   {\n      bucketName: 'bucket_name',\n      objectName: 'object_name',\n   },\n   // highlight-start\n   {\n      type: 'EDDSA',\n      address,\n      domain: window.location.origin,\n      seed: offChainData.seedString,\n   },\n   // highlight-end\n);\n
    const res = await client.object.getObject(\n   {\n      bucketName: 'bucket_name',\n      objectName: 'object_name',\n   },\n   // highlight-start\n   {\n      type: 'ECDSA',\n      privateKey: ACCOUNT_PRIVATEKEY,\n   }\n   // highlight-end\n);\n\n// res.body is Blob\nconsole.log('res', res)\nconst buffer = Buffer.from([res.body]);\nfs.writeFileSync('your_output_file', buffer)\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#code-repository","title":"Code Repository","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#api-documentation","title":"API Documentation","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/","title":"Contract Entrypoint - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#contract-entrypoint","title":"Contract Entrypoint","text":"

    Greenfield is based on a cross-chain programming model. It allows for the manipulation of data models on Greenfield via smart contracts on BSC or opBNB. These data models include objects, buckets, file permissions, and more. Below are the contract addresses deployed on various networks.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#bsc-mainnet","title":"BSC Mainnet","text":"

    DeployCommitId: c8e6a293b628f9063918ba8cd9c00ca41ded18db

    contract name address GovHub 0x1c9766EbcA1f38A06A04947129B394bF7FEc4599 CrossChain 0x77e719b714be09F70D484AB81F70D02B0E182f7d TokenHub 0xeA97dF87E6c7F68C9f95A69dA79E19B834823F25 LightClient 0x433bB48Bd86c089375e53b2E2873A9C4bC0e986B RelayerHub 0x31C477F05CE58bB81A9FB4b8c00560f1cBe185d1 BucketHub 0xE909754263572F71bc6aFAc837646A93f5818573 ObjectHub 0x634eB9c438b8378bbdd8D0e10970Ec88db0b4d0f GroupHub 0xDd9af4573D64324125fCa5Ce13407be79331B7F7 BucketERC721Token 0xC92d1d4b64Aebe28042206656b9E70E571A0E5eF ObjectERC721Token 0x4B92705a60d69f7A96aaDB8faa892526eB71adb7 GroupERC721Token 0x943FAC6CEBE6e45CE59bA911E5B6447c1a991450 MemberERC1155Token 0xAb73f243Be4d0fC5644c822351eC77e85DC2B5Ea PermissionHub 0xe1776006dBE9B60d9eA38C0dDb80b41f2657acE8 PermissionToken 0xE8d6aC02dB463c1463116c72A6164462B0660dEc MultiMessage 0x26204702935e2D617EE75B795152B9623a7d9809 GreenfieldExecutor 0xFa39D9111D927836b14D071d43e0aAD9cE83bBBf

    Extra:

    contract name address Deployer 0x4763c12b21a548BCbD22a682fb15930565e27C43 ProxyAdmin 0xf9010DC773eE3961418C96dc67Fc5DcCB3EA2C08

    For more details, you can refer to Greenfield Contracts Mainnet Deployment.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#bsc-testnet","title":"BSC Testnet","text":"

    DeployCommitId: 20cc1f5784a621438114847753cda289f3ed76fa

    contract name address GovHub 0xC8951B5DD89015DcD0606A63B23C8A67ae316302 CrossChain 0xa5B2c9194131A4E0BFaCbF9E5D6722c873159cb7 TokenHub 0xED8e5C546F84442219A5a987EE1D820698528E04 LightClient 0xa9249cefF9cBc9BAC0D9167b79123b6C7413F50a RelayerHub 0x91cA83d95c8454277d1C297F78082B589e6E4Ea3 BucketHub 0x5BB17A87D03620b313C39C24029C94cB5714814A ObjectHub 0x1b059D8481dEe299713F18601fB539D066553e39 GroupHub 0x50B3BF0d95a8dbA57B58C82dFDB5ff6747Cc1a9E BucketERC721Token 0xF6CB188D3346de442b171d015202e605B0697A2a ObjectERC721Token 0xc6a7192937961622D27956F412c4ce242F159311 GroupERC721Token 0x7fC61D6FCA8D6Ea811637bA58eaf6aB17d50c4d1 MemberERC1155Token 0x43bdF3d63e6318A2831FE1116cBA69afd0F05267 PermissionHub 0x25E1eeDb5CaBf288210B132321FBB2d90b4174ad PermissionToken 0xEBda3C285f79bEAF34416732F1F8Fa1e6B4B9dF7 MultiMessage 0x54be643072eB8cF38Ac0c57Abc72b9c0368C8699 GreenfieldExecutor 0x3E3180883308e8B4946C9a485F8d91F8b15dC48e

    Extra:

    contract name address Deployer 0x79aC4Ce73Cf5c4896a311CD39d2EB47E604D18E3 ProxyAdmin 0xdD1c0a54a9EDEa8d0821AEB5BE54c51B79fa4c2e

    For more details, you can refer to Greenfield Contracts Testnet Deployment.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#opbnb-testnet","title":"opBNB Testnet","text":"

    DeployCommitId: 6857ebfd2fd157c776cb8fc5f3dfb42696efeed2

    contract name address GovHub 0x64cB82CF53BE02fF56a3D5527beEF7302E740911 CrossChain 0xF0Bcf6E4F72bCB33b944275dd5c9d4540a259eB9 TokenHub 0x59614C9e9B5Df6dF4dc9e457cc7F3a67D796d3b2 LightClient 0xc50791892F6528E42A58DD07869726079C71F3f2 RelayerHub 0x59ACcF658CC4589C3C41720fd48e869B97A748a1 BucketHub 0xCAB5728B7cc21D0056E237D371b28efEEBFd8C2d ObjectHub 0xb23002c5C3DCe3312e190d9D186C4aB29F7cF26F GroupHub 0xe53725ac14bD77fA4754fC5a09889135C2c7Bc25 BucketERC721Token 0xCacc33C05ad335c929e62D87BB96D5c5E5A19641 ObjectERC721Token 0xb3e4d757b36A76fd968C97ed922Bd77AB2c72f62 GroupERC721Token 0x8C74F8e6cD4DCb307d344F358683594A68d66CD9 PermissionHub 0x089e97333da0B4260131068b7492D10fbEeC67BC PermissionToken 0x72705569ed3CC26dEC421f542191B8ac7F62c3e7 MultiMessage 0xc461eCE1922978d0336B03942cE70aCef4C5D09C GreenfieldExecutor 0x4bF975A172793FbcFff30Ffe5b3141A5C5aeBE52

    Extra:

    contract name address Deployer 0x84b3418faA3be4Bed168E2D00C7696b21008DcfD ProxyAdmin 0x9d067d0D30CA19bB24551c9b654B8b9BB83c8634

    For more details, you can refer to Greenfield Contracts Testnet Deployment.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#opbnb-mainnet","title":"opBNB Mainnet","text":"

    DeployCommitId: 6857ebfd2fd157c776cb8fc5f3dfb42696efeed2

    contract name address GovHub 0xCc63407862619bc65e5E09aFe521C6078C7fa730 CrossChain 0x7E376AEFAF05E20e3eB5Ee5c08fE1B9832b175cE TokenHub 0x723987D45BA424D562b087eE032b8C27F2E7b689 LightClient 0xf51ba131716776685A805E8E4Ecc95be2f923B93 RelayerHub 0xEd873b460C53D22f0FF3fc511854d9b8b16C4aE2 BucketHub 0xDbf8aEcB0F697A5c71baA0C1470Ba8D7f0395018 ObjectHub 0x8FcE352C1971cEa4c8b7b450C84780530713AcCd GroupHub 0x2968a07d24699F0Ffe1e17eCaebeF6BB50BCed68 BucketERC721Token 0x18C5f966795BC105B7F1bDf3313A540a0D62c22b ObjectERC721Token 0x9342750477676b257Cf28878320815dF94B78182 GroupERC721Token 0x488e054cc55Ba7a97e32B73122630364d4ffc050 MemberERC1155Token 0x9841F55651acd38019B8B895083F7B5f9933Ca44 PermissionHub 0x979876507F1395E5D391F9Dbef68468a22162B8D PermissionToken 0xb8AE22AA0B0F125B74D385261b26282a44224aCc MultiMessage 0x1aA380808eCef9BA5550fadaa97f2fD682B7f03A GreenfieldExecutor 0xdFc5DC31bfbf992C19C171db273A028736322Ec4

    Extra:

    contract name address Deployer 0xC6AA4CE979fbd263B8B32b9A162cA68F44D723a3 ProxyAdmin 0xD2e5D66A683d2dd67e8C9aAFb317Db96acfc3F00

    For more details, you can refer to Greenfield Contracts Mainnet Deployment.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/","title":"Integrating BSC Smart Contracts with Greenfield Projects - BNB Greenfield Cross Chain Integration","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#contract-sdk","title":"Contract SDK","text":"

    The Smart Contract SDK, designed to facilitate the development of community-driven projects. The SDK serves as an upper layer wrapper for the Greenfield-Contracts library, which implements the cross-chain communication functionality. By providing a user-friendly interface to the underlying interface, the SDK simplifies the development process and enables developers to create and manage a variety of greenfield resources, like bucket, group, and object on BSC through smart contract directly.

    The SDK is organized into four primary parts: BaseApp, BucketApp, ObjectApp, and GroupApp. These components serve as the building blocks for developers. The BaseApp serves as the foundation for the other three components, providing common functions required by the BucketApp, ObjectApp, and GroupApp.

    The BucketApp is responsible for managing bucket-related operations, while the ObjectApp handles object-related actions. The GroupApp, being the most complex of the four, is designed to handle group-related operations.

    Each of these components is equipped with unique functions and virtual functions that can be implemented to suit specific project needs.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#components","title":"Components","text":"
    1. BaseApp: Contains common functions used by the other components, as well as three virtual functions that need to be implemented for specific project requirements.
    2. BucketApp: A specialized module designed to handle bucket-related operations, such as creating and deleting buckets, and processing bucket resource calls.
    3. ObjectApp: A specialized module focused on object-related operations, specifically object deletion since creating objects from BSC is not supported.
    4. GroupApp: A more complex module that handles group-related operations, such as creating, deleting, and updating groups, and managing group resource calls.
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#baseapp","title":"BaseApp","text":"

    The BaseApp contains common functions that are shared by BucketApp, ObjectApp, and GroupApp. These functions are essential for setting up and managing the environment for cross-chain operations. The BaseApp provides the following core functions:

    1. _getTotalFee(): This function returns the total value required to send a cross-chain package.
    2. Setters: There are several setters available for configuring various aspects of the smart contract, such as:
    3. callbackGasLimit: Sets the gas limit for the callback function.
    4. failureHandleStrategy: Sets the strategy for handling failures during the execution of the smart contract.

    In addition to these functions, BaseApp provides three virtual functions:

    1. greenfieldCall(uint32 status, uint8 resourceType, uint8 operationType, uint256 resourceId, bytes calldata callbackData): This function is a callback hook designed to handle cross-chain response. It is a virtual function that needs to be implemented by developers to define custom behaviors for different types of resources and operation types. This function is triggered when a cross-chain operation is completed on greenfield side and return a package to bsc, allowing developers to execute specific actions or update states in response to the completion of an operation. If the developers don\u2019t need callback, this function(as well as other callback related functions) can be undefined.
    2. retryPackage(uint8 resourceType): This function handles the retry mechanism for a package, based on its resource type. Developers should implement this function to define the behavior when a package needs to be retried.
    3. skipPackage(uint8 resourceType): This function allows for skipping a package, based on its resource type. Developers should implement this function to define the behavior when a package needs to be skipped.

    By implementing these virtual functions, developers can customize the behavior of their smart contracts to meet their specific requirements. With the BaseApp component, developers have a solid foundation on which to build their smart contract applications using BucketApp, ObjectApp, and GroupApp.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#bucketapp","title":"BucketApp","text":"

    The BucketApp component is a specialized module designed to handle bucket-related operations in the smart contract SDK. This component offers a range of functions to create, delete, and manage buckets, as well as to route and handle various bucket resource operations. Below, we provide a detailed overview of the functions included in the BucketApp:

    1. _bucketGreenfieldCall(uint32 status, uint8 operationType, uint256 resourceId, bytes calldata callbackData): This function serves as a router for bucket resource callback. It processes and directs the call based on the provided parameters.
    2. _retryBucketPackage(): This function retries a failed bucket resource package.
    3. _skipBucketPackage(): This function skips a failed bucket resource package.
    4. _createBucket(address _creator, string memory _name, BucketStorage.BucketVisibilityType _visibility, address _paymentAddress, address _spAddress, uint256 _expireHeight, uint32 _globalVirtualGroupFamilyId, bytes calldata _sig, uint64 _chargedReadQuota): This function sends a create bucket cross-chain request to greenfield without a callback. It takes various parameters, such as creator, name, visibility type, charged read quota, service provider address, expire height, global virtual family id and signature.
    5. _createBucket(address _creator, string memory _name, BucketStorage.BucketVisibilityType _visibility, address _paymentAddress, address _spAddress, uint256 _expireHeight, uint32 _globalVirtualGroupFamilyId, bytes calldata _sig, uint64 _chargedReadQuota, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function sends a create bucket cross-chain request to greenfield with a callback. It takes the same parameters as the previous function, along with some additional parameters for the callback.
    6. _deleteBucket(uint256 _tokenId): This function sends a delete bucket cross-chain request to greenfield without a callback, using the provided token ID.
    7. _deleteBucket(uint256 _tokenId, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function sends a delete bucket cross-chain request to greenfield with a callback, using the provided token ID and callback data.

    In addition to these functions, the BucketApp provides two virtual functions:

    1. _createBucketCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers can implement this function to define the behavior for the create bucket callback. The function receives the status, token ID, and callback data as parameters.
    2. _deleteBucketCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers can implement this function to define the behavior for the delete bucket callback. The function receives the status, token ID, and callback data as parameters.

    By implementing these virtual functions, developers can tailor the BucketApp component to suit their specific bucket-related operations and handle the corresponding callbacks as needed.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#objectapp","title":"ObjectApp","text":"

    The ObjectApp component is a specialized module designed to handle object-related operations in the smart contract SDK. This component offers a range of functions to manage objects and process object resource operations. However, please note that creating objects from BSC is currently not supported. Below, we provide a detailed overview of the functions included in the ObjectApp:

    1. _objectGreenfieldCall(uint32 status, uint8 operationType, uint256 resourceId, bytes calldata callbackData): This function serves as a router for object resource callback. It processes and directs the call based on the provided parameters.
    2. _retryObjectPackage(): This function retries a failed object resource package.
    3. _skipObjectPackage(): This function skips a failed object resource package.
    4. _deleteObject(uint256 _tokenId): This function deletes an object using the provided token ID. As creating objects from BSC is not supported, the ObjectApp focuses on deletion operations.
    5. _deleteObject(uint256 _tokenId, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function deletes an object with a callback, using the provided token ID and callback data.

    In addition to these functions, the ObjectApp provides one virtual function:

    1. _deleteObjectCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers need to implement this function to define the behavior for the delete object callback. The function receives the status, token ID, and callback data as parameters.

    By implementing this virtual function, developers can customize the ObjectApp component to handle object deletion operations and manage the corresponding callbacks as needed.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#groupapp","title":"GroupApp","text":"

    The GroupApp component is a specialized module designed to handle group-related operations in the smart contract SDK. This component is more complex compared to the BucketApp and ObjectApp, as it offers a range of functions to create, delete, update, and manage groups. Below, we provide a detailed overview of the functions included in the GroupApp:

    1. _groupGreenfieldCall(uint32 status, uint8 operationType, uint256 resourceId, bytes calldata callbackData): This function serves as a router for group resource callback. It processes and directs the call based on the provided parameters.
    2. _retryGroupPackage(): This function retries a failed group resource package.
    3. _skipGroupPackage(): This function skips a failed group resource package.
    4. _createGroup(address _owner, string memory _groupName): This function creates a new group with the provided owner address and group name.
    5. _createGroup(address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData,, address _owner, string memory _groupName, uint256 _callbackGasLimit): This function creates a new group with a callback, using the provided owner address, group name, and callback data.
    6. _deleteGroup(uint256 _tokenId): This function deletes a group using the provided token ID.
    7. _deleteGroup(uint256 _tokenId, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function deletes a group with a callback, using the provided token ID and callback data.
    8. _updateGroup(address _owner, uint256 _tokenId, uint8 _opType, address[] memory _members, uint64[] memory _expiration): This function updates a group based on the provided owner address, token ID, operation type, and an array of member addresses.
    9. _updateGroup(address _owner, uint256 _tokenId, uint8 _opType, address[] memory _members, uint64[] memory _expiration, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function updates a group with a callback, using the provided owner address, token ID, operation type, an array of member addresses, and callback data.

    In addition to these functions, the GroupApp provides three virtual functions:

    1. _createGroupCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers need to implement this function to define the behavior for the create group callback. The function receives the status, token ID, and callback data as parameters.
    2. _deleteGroupCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers need to implement this function to define the behavior for the delete group callback. The function receives the status, token ID, and callback data as parameters.
    3. _updateGroupCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers need to implement this function to define the behavior for the update group callback. The function receives the status, token ID, and callback data as parameters.

    By implementing these virtual functions, developers can customize the GroupApp component to suit their specific group-related operations and handle the corresponding callbacks as needed.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#integration-example","title":"Integration Example","text":"

    We will walk you through the process of creating a decentralized Ebook shop using the Contract SDK as an example.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#prerequisites","title":"Prerequisites","text":"

    Before starting, make sure you have the following tools installed:

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#installation","title":"Installation","text":"
    $ npm install @bnb-chain/greenfield-contracts-sdk\n

    Alternatively, you can obtain the contracts directly from the GitHub repository (bnb-chain/greenfield-contracts-sdk). When doing so, ensure that you specify the appropriate release.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#steps","title":"Steps","text":"
    1. Import the desired contracts, for example in examples/ebook-shop.sol:
    pragma solidity ^0.8.0;\n\nimport \"@bnb-chain/greenfield-contracts-sdk/BucketApp.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/ObjectApp.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/GroupApp.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/interface/IERC1155.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/interface/IERC721NonTransferable.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/interface/IERC1155NonTransferable.sol\";\n...\n\ncontract EbookShop is BucketApp, ObjectApp, GroupApp {\n ...\n}\n
    1. Define the initialize function. Initialize the global variables in the init function. You can use the internal init functions:

      function initialize(\n    address _crossChain,\n    address _bucketHub,\n    address _objectHub,\n    address _groupHub,\n    address _ebookToken,\n    address _paymentAddress,\n    uint256 _callbackGasLimit,\n    address _refundAddress,\n    uint8 _failureHandleStrategy,\n    ...\n) public initializer {\n    __base_app_init_unchained(_crossChain, _callbackGasLimit, _refundAddress, _failureHandleStrategy);\n    __bucket_app_init_unchained(_bucketHub);\n    __group_app_init_unchained(_groupHub);\n    __object_app_init_unchained(_objectHub);\n\n    ...\n}\n
    2. Define and override the greenfieldCall, retryPackage and skipPackage functions if your dApp needs callback. You can route calls with the help of the internal method:

      function greenfieldCall(\n    uint32 status,\n    uint8 resoureceType,\n    uint8 operationType,\n    uint256 resourceId,\n    bytes calldata callbackData\n) external override(BucketApp, ObjectApp, GroupApp) {\n    require(msg.sender == crossChain, string.concat(\"EbookShop: \", ERROR_INVALID_CALLER));\n\n    if (resoureceType == RESOURCE_BUCKET) {\n        _bucketGreenfieldCall(status, operationType, resourceId, callbackData);\n    } else if (resoureceType == RESOURCE_OBJECT) {\n        _objectGreenfieldCall(status, operationType, resourceId, callbackData);\n    } else if (resoureceType == RESOURCE_GROUP) {\n        _groupGreenfieldCall(status, operationType, resourceId, callbackData);\n    } else {\n        revert(string.concat(\"EbookShop: \", ERROR_INVALID_RESOURCE));\n    }\n}\n\nfunction retryPackage(uint8 resoureceType) external override onlyOperator {\n    if (resoureceType == RESOURCE_BUCKET) {\n        _retryBucketPackage();\n    } else if (resoureceType == RESOURCE_OBJECT) {\n        _retryObjectPackage();\n    } else if (resoureceType == RESOURCE_GROUP) {\n        _retryGroupPackage();\n    } else {\n        revert(string.concat(\"EbookShop: \", ERROR_INVALID_RESOURCE));\n    }\n}\n\nfunction skipPackage(uint8 resoureceType) external override onlyOperator {\n    if (resoureceType == RESOURCE_BUCKET) {\n        _skipBucketPackage();\n    } else if (resoureceType == RESOURCE_OBJECT) {\n        _skipObjectPackage();\n    } else if (resoureceType == RESOURCE_GROUP) {\n        _skipGroupPackage();\n    } else {\n        revert(string.concat(\"EbookShop: \", ERROR_INVALID_RESOURCE));\n    }\n}\n
    3. Next you need to define the main functional parts of the app. You can send cross-chain request to system contracts with the help of internal functions like below:

      /**\n * @dev Create a new series.\n * \n * Assuming the sp provider's info will be provided by the front-end.\n */\nfunction createSeries(\n    string calldata name,\n    BucketStorage.BucketVisibilityType visibility,\n    uint64 chargedReadQuota,\n    address spAddress,\n    uint256 expireHeight,\n    bytes calldata sig\n) external payable {\n    require(bytes(name).length > 0, string.concat(\"EbookShop: \", ERROR_INVALID_NAME));\n    require(seriesId[name] == 0, string.concat(\"EbookShop: \", ERROR_RESOURCE_EXISTED));\n\n    bytes memory _callbackData = bytes(name); // use name as callback data\n    _createBucket(msg.sender, name, visibility, chargedReadQuota, spAddress, expireHeight, sig, _callbackData); // send cross-chain request\n}\n\n/**\n * @dev Provide an ebook's ID to publish it.\n *\n * An ERC1155 token will be minted to the owner.\n * Other users can buy the ebook by calling `buyEbook` function with given price.\n */\nfunction publishEbook(uint256 _ebookId, uint256 price) external {\n    require(\n        IERC721NonTransferable(objectToken).ownerOf(_ebookId) == msg.sender,\n        string.concat(\"EbookShop: \", ERROR_INVALID_CALLER)\n    );\n    require(ebookGroup[_ebookId] != 0, string.concat(\"EbookShop: \", ERROR_GROUP_NOT_EXISTED));\n    require(price > 0, string.concat(\"EbookShop: \", ERROR_INVALID_PRICE));\n\n    ebookPrice[_ebookId] = price;\n    IERC1155(ebookToken).mint(msg.sender, _ebookId, 1, \"\");\n}\n\n/**\n * @dev Provide an ebook's ID to buy it.\n *\n * Buyer will be added to the group of the ebook.\n * An ERC1155 token will be minted to the buyer.\n */\nfunction buyEbook(uint256 _ebookId) external payable {\n    require(ebookPrice[_ebookId] > 0, string.concat(\"EbookShop: \", ERROR_EBOOK_NOT_ONSHELF));\n\n    uint256 price = ebookPrice[_ebookId];\n    require(msg.value >= price, string.concat(\"EbookShop: \", ERROR_NOT_ENOUGH_VALUE));\n\n    IERC1155(ebookToken).mint(msg.sender, _ebookId, 1, \"\");\n\n    uint256 _groupId = ebookGroup[_ebookId];\n    address _owner = IERC721NonTransferable(groupToken).ownerOf(_groupId);\n    address[] memory _member = new address[](1);\n    _member[0] = msg.sender;\n    _updateGroup(_owner, _groupId, UPDATE_ADD, _member);\n}\n\n/**\n * @dev Provide an ebook's ID to downshelf it.\n *\n * The ebook will be removed from the shelf and cannot be bought.\n * Those who have already purchased are not affected.\n */\nfunction downshelfEbook(uint256 _ebookId) external {\n    require(\n        IERC721NonTransferable(objectToken).ownerOf(_ebookId) == msg.sender,\n        string.concat(\"EbookShop: \", ERROR_INVALID_CALLER)\n    );\n    require(ebookPrice[_ebookId] > 0, string.concat(\"EbookShop: \", ERROR_EBOOK_NOT_ONSHELF));\n\n    ebookPrice[_ebookId] = 0;\n}\n...\n
    4. Besides, you may need to provide a function for user to register their own resource that were created at greenfield side and then mirrored to BSC manually:

      /**\n * @dev Register bucket resource that mirrored from GreenField to BSC.\n */\nfunction registerSeries(string calldata name, uint256 tokenId) external {\n    require(\n        IERC721NonTransferable(bucketToken).ownerOf(tokenId) == msg.sender,\n        string.concat(\"EbookShop: \", ERROR_INVALID_CALLER)\n    );\n    require(bytes(name).length > 0, string.concat(\"EbookShop: \", ERROR_INVALID_NAME));\n    require(seriesId[name] == 0, string.concat(\"EbookShop: \", ERROR_RESOURCE_EXISTED));\n\n    seriesName[tokenId] = name;\n    seriesId[name] = tokenId;\n}\n...\n
    5. Define other view functions, internal functions and access control system according to your own needs.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/","title":"Contract as Bucket Owner - BNB Greenfield Demo","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#greenfield-demo-contract-as-bucket-owner","title":"Greenfield Demo: Contract as Bucket Owner","text":"

    BNB Greenfield provides the ability for a contract to manage buckets through greenfield cross-chain transactions, and we\u2019ll use a demo to briefly demonstrate the process.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#greenfield-demo-contract","title":"Greenfield Demo Contract","text":"

    The Demo includes the following parts:

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#greenfield-contracts-constant","title":"greenfield contracts constant:","text":"
        // BSC testnet\n    address public constant TOKEN_HUB = 0xED8e5C546F84442219A5a987EE1D820698528E04;\n    address public constant CROSS_CHAIN = 0xa5B2c9194131A4E0BFaCbF9E5D6722c873159cb7;\n    address public constant BUCKET_HUB = 0x5BB17A87D03620b313C39C24029C94cB5714814A;\n    address public constant PERMISSION_HUB = 0x25E1eeDb5CaBf288210B132321FBB2d90b4174ad;\n    address public constant SP_ADDRESS_TESTNET = 0x5FFf5A6c94b182fB965B40C7B9F30199b969eD2f;\n    address public constant GREENFIELD_EXECUTOR = 0x3E3180883308e8B4946C9a485F8d91F8b15dC48e;\n
    The addresses of Greenfield contracts deployed on the BSC testnet are available and configured here. You can find contracts deployed on other networks contract entrypoint"},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#create-bucket-and-set-bucket-flow-rate-limit","title":"create bucket and set bucket flow rate limit","text":"
        function createBucket(string memory bucketName, uint256 transferOutAmount, bytes memory _executorData) external payable;\n
    Provides the bucket name, initial BNB amount transferred to the demo contract on Greenfield and the executor data to set bucket flow rate limit.This API will create a new bucket owned by the smart contract and set the payment for it."},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#create-policy-to-allow-eoa-account-to-upload-files-to-the-bucket","title":"create policy to allow eoa account to upload files to the bucket","text":"
        function createPolicy(bytes memory createPolicyData) external payable;\n
    Construct the createPolicyData parameters to grant permission to the dedicated principle for the created bucket owned by the smart contract."},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#interact-script","title":"Interact Script","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#installation","title":"Installation","text":"
    git clone https://github.com/bnb-chain/greenfield-contracts.git\ncd greenfield-contracts && git checkout develop\nnpm install\nnpx hardhat compile\n\ncp .env.example .env\n# set `DeployerPrivateKey` on .env\n# make sure the tBNB balance of the account >= 0.5 BNB on BSC Testnet\nnpx hardhat run scripts/11-demo-contract-approve-eoa-upload.ts  --network bsc-testnet\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#workflow","title":"Workflow","text":"

    The interact script includes 4 steps as follows:

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#deploy-demo-contract","title":"deploy demo contract","text":"
        const demo = (await deployContract(operator, 'GreenfieldDemo')) as GreenfieldDemo;\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#create-bucket-whose-owner-is-the-demo-contract","title":"create bucket whose owner is the demo contract","text":"

    set bucket flow rate limit and cross-chain transfer 0.1 BNB to demo contract

    const bucketName = 'test-' + demo.address.substring(2, 6).toLowerCase();\n// - transferOutAmt: 0.1 BNB to demo contract on Greenfield\n// - set bucket flow rate limit to this bucket\n// - create bucket: 'test-approve-eoa-upload', its owner is demo contract\nconst dataSetBucketFlowRateLimit = ExecutorMsg.getSetBucketFlowRateLimitParams({\n    bucketName,\n    bucketOwner: demo.address,\n    operator: demo.address,\n    paymentAddress: demo.address,\n    flowRateLimit: '1000000000000000000',\n});\nconst executorData = dataSetBucketFlowRateLimit[1];\nconst transferOutAmt = ethers.utils.parseEther('0.1');\nconst value = transferOutAmt.add(relayFee.mul(3).add(ackRelayFee.mul(2)));\n\nlog('- transfer out to demo contract on greenfield', toHuman(transferOutAmt));\nlog('- create bucket', bucketName);\nlog('send crosschain tx!');\nconst receipt = await waitTx(\n    demo.createBucket(bucketName, transferOutAmt, executorData, { value })\n);\nlog(`https://testnet.bscscan.com/tx/${receipt.transactionHash}`);\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#get-bucket-id-by-name-after-bucket-created","title":"get bucket id by name after bucket created","text":"
    const bucketInfo = await client.bucket.getBucketMeta({ bucketName });\nconst bucketId = bucketInfo.body!.GfSpGetBucketMetaResponse.Bucket.BucketInfo.Id;\nlog('bucket created, bucket id', bucketId);\nconst hexBucketId = `0x000000000000000000000000000000000000000000000000000000000000${BigInt(\n    bucketId\n).toString(16)}`;\nlog(`https://testnet.greenfieldscan.com/bucket/${hexBucketId}`);\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#create-policy-to-allow-eoa-account-upload-files-to-the-bucket-through-cross-chain-transaction","title":"create policy to allow EOA account upload files to the bucket through cross-chain transaction","text":"
    const uploaderEoaAccount = operator.address; // TODO set your eoa account to upload files\nlog('try to set uploader(eoa account) is', uploaderEoaAccount);\n\nconst policyDataToAllowUserOperateBucket = Policy.encode({\n    id: '0',\n    resourceId: bucketId, // bucket id\n    resourceType: ResourceType.RESOURCE_TYPE_BUCKET,\n    statements: [\n        {\n            effect: Effect.EFFECT_ALLOW,\n            actions: [ActionType.ACTION_CREATE_OBJECT], // allow upload file to the bucket\n            resources: [],\n        },\n    ],\n    principal: {\n        type: PrincipalType.PRINCIPAL_TYPE_GNFD_ACCOUNT,\n        value: uploaderEoaAccount,\n    },\n}).finish();\n\nawait waitTx(\n    demo.createPolicy(policyDataToAllowUserOperateBucket, { value: relayFee.add(ackRelayFee) })\n);\n

    Now the deployer account can upload files to the bucket on Greenfield.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/","title":"EVM Programmability - BNB Greenfield Cross Chain","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#evm-programmability","title":"EVM Programmability","text":"

    This document give a detailed introduction of cross-chain primitives that have been defined on EVM-compatible chains to enable developers to manage greenfield resources on the EVM-compatible chains directly.

    The Greenfield-Contracts Repo is the underlying backbone of the cross chain communication protocol. It is responsible for implementing the core cross-chain communication functionality that enables seamless interaction between Greenfield and EVM-compatible chains, like BSC and opBNB. The library handles the complexities of cross-chain operations, ensuring secure and efficient communication.

    During the development process, developers are most likely to interact with the following contracts: CrossChain, BucketHub, ObjectHub, GroupHub, PermissionHub, MultiMessage and GreenfieldExecutor.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#quick-glance","title":"Quick Glance","text":"Contract name Usage GovHub Handle system governance request CrossChain Handle cross-chain package TokenHub Transfer BNB from BSC to Greenfield LightClient Verify cross-chain package and sync light block RelayerHub Relayers could claim rewards from RelayerHub BucketHub Create/delete bucket ObjectHub Delete object GroupHub Create/delete group, update group member BucketERC721Token ERC721 token address representing buckets ownership ObjectERC721Token ERC721 token address representing objects ownership GroupERC721Token ERC721 token address representing groups ownership MemberERC1155Token ERC71155 token address representing the identity of group members PermissionHub The user can use Resource-Based Policy to grant permissions to other accounts. Any resources, such as buckets, objects and groups, can associate several policy. Only the resource owner can put a policy which associate to a resource he owned. 1. A policy associate to a bucket can allow grantee to operate the bucket or the specific objects. 2. A policy associate to a object/group can only allow to operator the object/group. PermissionToken ERC721 token address representing resource policy MultiMessage MultiMessage provides aggregation capabilities to support the atomicity of composite operations. GreenfieldExecutor Most native operations can be achieved by GreenfieldExecutor, like create payment account, deposit to payment account, withdraw from payment account, migrate bucket, cancel migrate bucket, update bucket info, toggle SP as delegated agent, set bucket flow ratelimit, copy object, update object info, set tag.

    Refer to the contract list for detailed contract address on different network.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#callback-handling","title":"CallBack Handling","text":"

    dApps on EVM-compatible chains, i.e. smart contracts on BSC, are allowed to implement their own logic to handle ACK and FAIL_ACK packages. The smart contracts can register callback functions to handle the ACK packages. To avoid consuming too much gas in callbacks, a gas limitation estimation should be done by the smart contracts that register the callbacks.

    Errors and failures can occur during cross-chain communication. dApps on EVM-compatible chains can handle these by retrying the package with a higher gas limit, skipping the package to tolerate failure, or upgrading their contract to handle corner cases.

    The following are the interfaces for dapps to handle failures:

     // retry the first failed package in the queue\n function retryPackage() external;\n // skip the first failed package in the queue\n function skipPackage() external;\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#permission-programmability","title":"Permission Programmability","text":"

    Whether resources are created on BSC or mapped from Greenfield to BSC, such as Buckets, Objects, and Groups, by default, only the owner account of these resources can manage them. However, with proper authorization, other accounts or contracts can be allowed to operate on the owner\u2019s resources. We provide two methods of authorization:

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#role-based-authorization","title":"Role-based authorization","text":"

    BucketHub, ObjectHub, and GroupHub all implement the following interface. Through the grant interface, other accounts can be granted the permission to create, delete, and update this type of resource for a certain period. This permission can also be revoked through the revoke interface.

    function grant(address account, uint32 acCode, uint256 expireTime) external {\n ...\n}\nfunction revoke(address account, uint32 acCode) external {\n    ...\n}\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#nft-token-authorization","title":"NFT token authorization","text":"

    Since BucketHub and ObjectHub implement the NFT721 standard, and GroupHub implements the ERC1155 standard, we use approve and setApprovalForAll to authorize specific resource Token IDs without restricting the types of operations, meaning both deletion and updating are allowed.

    function approve(address to, uint256 tokenId) public virtual {\n    ...\n}\nfunction setApprovalForAll(address operator, bool approved) public virtual {\n    ...\n}\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#detailed-interface","title":"Detailed Interface","text":"

    They provide the following interfaces respectively:

    IGroupHub

    The GroupHub contract provides the following interfaces to manage Group on BSC/opBNB directly.

    interface IGroupHub {\n    /** \n     * @dev  Query the contract address of group NFT.\n     * @return The contract address of group token.\n     * Each group will be mapped as a NFT on BSC.\n     * Group ID and NFT token ID are the same.\n     */\n    function ERC721Token() external view returns (address);\n    /** \n     * @dev  Query the contract address of member NFT.\n     * @return The contract address of member token.\n     * The member inside a group  will be mapped as a ERC1155 token on BSC.\n     * The ID of the ERC1155 token is same with the group ID.\n     */\n    function ERC1155Token() external view returns (address);\n\n    /**\n     * @dev create a group and send cross-chain request from BSC to GNFD.\n     *\n     * @param creator The group's owner.\n     * @param name The group's name.\n     */\n    function createGroup(address creator, string memory name) external payable returns (bool);\n\n    /**\n     * @dev create a group and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param creator The group's owner.\n     * @param name The group's name.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function createGroup(\n        address creator,\n        string memory name,\n        uint256 callbackGasLimit,\n        CmnStorage.ExtraData memory extraData\n    ) external payable returns (bool);\n\n    /**\n     * @dev delete a group and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The group's id.\n     */\n    function deleteGroup(uint256 id) external payable returns (bool);\n\n    /**\n     * @dev delete a group and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param id The group's id.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function deleteGroup(uint256 id, uint256 callbackGasLimit, CmnStorage.ExtraData memory extraData) external payable returns (bool);\n\n    /**\n     * @dev update a group's member and send cross-chain request from BSC to GNFD.\n     *\n     * @param synPkg Package containing information of the group to be updated.\n     */\n    function updateGroup(GroupStorage.UpdateGroupSynPackage memory synPkg) external payable returns (bool);\n\n    /**\n     * @dev update a group's member and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param synPkg Package containing information of the group to be updated.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function updateGroup(\n        GroupStorage.UpdateGroupSynPackage memory synPkg,\n        uint256 callbackGasLimit,\n        CmnStorage.ExtraData memory extraData\n    ) external payable returns (bool);\n\n    /**\n     * @dev Prepare the create group cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param owner The group's owner.\n     * @param name The group's name.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreateGroup(\n        address sender,\n        address owner,\n        string memory name\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete group cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The group's id.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteGroup(\n        address sender,\n        uint256 id\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the update group cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param synPkg Package containing information of the group to be updated.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareUpdateGroup(\n        address sender,\n        GroupStorage.UpdateGroupSynPackage memory synPkg\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n}\n

    IBucketHub

    The BucketHub contract provides the following interfaces to manage bucket on EVM-compatible chains, like BSC and opBNB, directly.

    interface IBucketHub {\n    /** \n     * @dev  Query the contract address of bucket NFT.\n     * @return The contract address of bucket token.\n     * Each bucket will be mapped as a NFT on BSC.\n     * Bucket ID and NFT token ID are the same.\n     */\n    function ERC721Token() external view returns (address);\n\n    /**\n     * @dev create a bucket and send cross-chain request from BSC to GNFD\n     *\n     * @param synPkg Package containing information of the bucket to be created\n     */\n    function createBucket(BucketStorage.CreateBucketSynPackage memory synPkg) external payable returns (bool);\n\n    /**\n     * @dev create a bucket and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param synPkg Package containing information of the bucket to be created.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function createBucket(\n        BucketStorage.CreateBucketSynPackage memory synPkg,\n        uint256 callbackGasLimit,\n        CmnStorage.ExtraData memory extraData\n    ) external payable returns (bool);\n\n    /**\n     * @dev delete a bucket and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The bucket's id.\n     */\n    function deleteBucket(uint256 id) external payable returns (bool);\n\n    /**\n     * @dev delete a bucket and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param id The bucket's id.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function deleteBucket(uint256 id, uint256 callbackGasLimit, CmnStorage.ExtraData memory extraData) external payable returns (bool);\n\n    /**\n     * @dev Prepare the create bucket cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param synPkg Package containing information of the bucket to be created.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreateBucket(\n        address sender,\n        CreateBucketSynPackage memory synPkg\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the create bucket cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param synPkg Package containing information of the bucket to be created.\n     * @param callbackGasLimit The gas limit for callback function\n     * @param extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreateBucket(\n        address sender,\n        CreateBucketSynPackage memory synPkg, \n        uint256 callbackGasLimit,\n        CmnStorage.ExtraData memory extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete bucket cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The bucket's id.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteBucket(\n        address sender,\n        uint256 id\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete bucket cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The bucket's id.\n     * @param callbackGasLimit The gas limit for callback function\n     * @param extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteBucket(\n        address sender,\n        uint256 id,\n        uint256 callbackGasLimit,\n        ExtraData memory extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n}\n

    IObjectHub

    The ObjectHub contract provides the following interfaces to manage object on EVM-compatible chains, like BSC and opBNB, directly.

    interface IObjectHub {\n    /** \n     * @dev  Query the contract address of object NFT.\n     * @return The contract address of object token.\n     * Each object will be mapped as a NFT on BSC.\n     * Object ID and NFT token ID are the same.\n     */\n    function ERC721Token() external view returns (address);\n\n    /**\n     * @dev delete a object and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The object's id.\n     */\n    function deleteObject(uint256 id) external payable returns (bool);\n\n    /**\n     * @dev delete a object and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param id The object's id.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function deleteObject(uint256 id, uint256 callbackGasLimit, CmnStorage.ExtraData memory extraData) external payable returns (bool);\n\n    /**\n     * @dev Prepare the delete object cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The object's id.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteObject(\n        address sender,\n        uint256 id\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete object cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The object's id.\n     * @param callbackGasLimit The gas limit for callback function\n     * @param extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteObject(\n        address sender,\n        uint256 id,\n        uint256 callbackGasLimit,\n        ExtraData memory extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n}\n

    IPermissionHub

    The PermissionHub contract provides the following interfaces to manage permission on EVM-compatible chains, like BSC and opBNB, directly.

    interface IPermissionHub {\n    /** \n     * @dev  Query the contract address of permission NFT.\n     * @return The contract address of permission token.\n     * Each permission policy will be mapped as a NFT on BSC.\n     * Policy ID and NFT token ID are the same.\n     */\n    function ERC721Token() external view returns (address);\n\n    /**\n     * @dev delete a policy and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The policy's id.\n     */\n    function deletePolicy(uint256 id) external payable returns (bool);\n\n    /**\n     * @dev delete a policy and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The policy's id.\n     * @param _extraData Extra data for callback function.\n     */\n    function deletePolicy(uint256 id, PermissionStorage.ExtraData memory _extraData) external payable returns (bool);\n\n    /**\n     * @dev create a policy and send cross-chain request from BSC to GNFD.\n     *\n     * @param data policy data encoded by protobuf.\n     * @param _extraData Extra data for callback function.\n     */\n    function createPolicy(\n        bytes calldata _data, \n        PermissionStorage.ExtraData memory _extraData\n    ) external payable returns (bool);\n\n    /**\n     * @dev create a policy and send cross-chain request from BSC to GNFD.\n     *\n     * @param _data policy data encoded by protobuf.\n     */\n    function createPolicy(bytes calldata _data) external payable returns (bool);\n\n    /**\n     * @dev Prepare the create policy cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param _data policy data encoded by protobuf.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreatePolicy(\n        address sender, \n        bytes calldata _data\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the create policy cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param _data policy data encoded by protobuf.\n     * @param _extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreatePolicy(\n        address sender, \n        bytes calldata _data, \n        PermissionStorage.ExtraData memory _extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete policy cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The policy's id.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeletePolicy(\n        address sender, \n        uint256 id\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete policy cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The policy's id.\n     * @param _extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeletePolicy(\n        address sender, \n        uint256 id, \n        PermissionStorage.ExtraData memory _extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n

    IMultiMessage

    MultiMessage provides aggregation capabilities to support the atomicity of composite operations.

    interface IMultiMessage {\n    function sendMessages(\n        address[] calldata _targets,\n        bytes[] calldata _data,\n        uint256[] calldata _values\n    ) external payable returns (bool);\n}\n

    IGreenfieldExecutor

    Most native operations can be achieved by GreenfieldExecutor, like create payment account, deposit to payment account, withdraw from payment account, migrate bucket, cancel migrate bucket, update bucket info, toggle SP as delegated agent, set bucket flow ratelimit, copy object, update object info, set tag.

    interface IGreenfieldExecutor {\n    function execute(uint8[] calldata _msgTypes, bytes[] calldata _msgBytes) external payable returns (bool);\n}\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/","title":"Resource Mirroring - BNB Greenfield Cross Chain","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/#resource-mirroring","title":"Resource Mirroring","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/#overview","title":"Overview","text":"

    Greenfield Blockchain offers resources like buckets, objects, and groups for mirroring on EVM-compatible chains (e.g., BSC, opBNB) as ERC-721 NFTs.

    Buckets serve as containers for objects, which are data files with metadata, while groups are sets of accounts with shared permissions. Additionally, group members\u2019 permissions can be mirrored as ERC-1155 tokens. Currently, these NFTs are non-transferable, with plans to introduce transferability soon.

    Mirrored resources on EVM chains can be managed via smart contracts, impacting data\u2019s storage format and access permissions. Changes on EVM chains reflect on Greenfield, enhancing data access and manipulation flexibility. This integration fosters a more efficient data management process.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/#how-to-mirror","title":"How to Mirror","text":"

    Mirroring objects from BNB Greenfield to BSC is not done automatically with the creation of the resource. Users have to manually trigger the mirroring process for selected objects, either at the bucket or object level or group, as it requires transaction gas. This allows users to have control over which objects are mirrored while being aware of the associated costs.

    The changes made to mirrored objects on BSC are propagated to BNB Greenfield once the corresponding transactions are finalized on both blockchains. BSC has a block finality of 3 seconds, while BNB Greenfield has a block finality of 2 seconds. As a result, the changes should be reflected within a maximum block finality of 3 seconds, which is the longer of the two block finality times.

    Once an object is mirrored from BNB Greenfield to BSC, it can only be managed on BSC and cannot be reverted or \u201cun-mirrored\u201d back to Greenfield for management through Greenfield. However, it is worth noting that the ability to \u201cun-mirror\u201d objects back to Greenfield may be introduced in future releases, providing the option to manage mirrored objects through Greenfield after being mirrored to BSC.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/#what-can-be-achieved-through-mirroring","title":"What can be achieved through mirroring","text":"

    Currently changing any metadata attributes of the object, which includes information about its properties, permissions, and other relevant attributes. For instance, to alter an object\u2019s permissions on BNB Greenfield, a user can execute an on-chain transaction on BSC. This transaction, specifying the permission changes, sends a message via relayers from BSC to Greenfield. Upon receiving the message, Greenfield updates the object\u2019s metadata as requested.

    During the mirroring process from BNB Greenfield to BSC, the content of the file itself is not copied. This means that neither the data nor the file metadata, which is stored on the BNB Greenfield blockchain, is transferred to BSC. Consequently, there is no size limit imposed on the mirroring process since the actual file content is not duplicated. The ownership of the resource is changed too during the mirroring process.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/","title":"Resources Mirroring with CLI - BNB Greenfield Cross Chain Integration","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#resources-mirroring-with-cli","title":"Resources Mirroring with CLI","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#introduction","title":"Introduction","text":"

    During the mirroring process from BNB Greenfield to BSC, the content of the file itself is not copied. This means that neither the data nor the file metadata, which is stored on the BNB Greenfield blockchain, is transferred to BSC. Consequently, there is no size limit imposed on the mirroring process since the actual file content is not duplicated.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#mirror-objects","title":"Mirror Objects","text":"

    Objects can be mirrored on the BSC as ERC-721 NFTs

    Example command to mirror to BSC testnet:

    gnfd-cmd object mirror --bucketName yourBucketName --objectName yourObjectName --destChainId 97\n

    Example output:

    mirror object succ, txHash: 0774F400EBD42FAB009A6B3C303EF8625B57AB551E0F065C546B892167938122\n
    You can go to GreenfieldScan to view the details of mirror operation.

    Then, go to BscScan and you can find out that there is a NFT transferred to you.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#mirror-buckets","title":"Mirror Buckets","text":"

    Mirror buckets are the same procedure and mirror objects.

    Example command to mirror to BSC testnet:

    gnfd-cmd object mirror --bucketName yourBucketName  --destChainId 97\n

    Example output:

    mirror bucket succ, txHash: 0xba1ca47a2271864b2010158b13535331301ba3289aab8e373503e91e3a41d0a7\n
    You can go to GreenfieldScan to view the details of mirror operation.

    Then, go to BscScan and you can find out that there is a NFT transferred to you.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#mirror-group","title":"Mirror Group","text":"

    The members within a group, which represent permissions to specify resources, can be mirrored as ERC-1155 token.

    Example command to mirror to BSC testnet:

    // mirror a group as NFT to BSC, you might use group id or groupName to identidy the group\ngnfd-cmd group mirror --id 1\n// irror a group with group id\ngnfd-cmd group mirror --groupName yourGroupName\n

    Example output:

    mirror_group:\ntransaction hash: 99A749ECC3CEB8B7CF4B8132A19D1A04EF7247F8549477B6AD28CA69BD11E66A\n
    You can go to GreenfieldScan to view the details of mirror operation.

    Then, go to BscScan and you can find out that there is a NFT transferred to you.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/","title":"Cross Chain Program FAQ - BNB Greenfield Cross Chain Integration","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#cross-chain-program-faq","title":"Cross Chain Program FAQ","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#what-are-the-advantages-of-mirroring","title":"What are the advantages of mirroring?","text":"

    By transferring control over objects to the smart contract on BSC and allowing on-chain management, object mirroring enables greater flexibility and control over decentralized storage on BNB Greenfield to all dApps on BSC. It leverages the capabilities of the BSC and its smart contract functionality to provide enhanced functionality and interoperability between the two platforms.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#how-mirroring-is-actually-implemented-on-bsc","title":"How mirroring is actually implemented on BSC?","text":"

    Mirroring on BSC allows for the replication of resources from the Greenfield Blockchain to BSC as non-fungible tokens (NFTs). These resources include buckets, objects, and groups, which are represented as NFTs conforming to the ERC-721 standard. Additionally, the members within a group can be mirrored as ERC-1155 tokens, representing permissions.

    Once mirrored on BSC, these resources can be managed directly by smart contracts on the BSC network. Any operations performed on BSC will impact the storage format, access permissions, and other aspects of the data on Greenfield, ensuring that changes made on BSC are reflected on Greenfield. Currently, the mirrored NFTs are not transferable, but the ability to transfer them will be introduced in the future.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#are-objects-mirrored-by-default-over-to-bsc","title":"Are objects mirrored by default over to BSC?","text":"

    Mirroring objects from BNB Greenfield to BSC is not done automatically with the creation of the object. Users have to manually trigger the mirroring process for selected objects, either at the bucket or object level, as it requires transaction gas. This allows users to have control over which objects are mirrored while being aware of the associated costs.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#how-long-the-changes-are-propagated-from-mirrored-bsc-objects-to-actual-change-on-bnb-greenfield","title":"How long the changes are propagated from mirrored BSC objects to actual change on BNB Greenfield?","text":"

    The changes made to mirrored objects on BSC are propagated to BNB Greenfield once the corresponding transactions are finalized on both blockchains. BSC has a block finality of 3 seconds, while BNB Greenfield has a block finality of 2 seconds. As a result, the changes should be reflected within a maximum block finality of 3 seconds, which is the longer of the two block finality times.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#if-the-object-is-renamed-does-the-mirroring-break-and-need-to-be-remirrored","title":"If the object is renamed, does the mirroring break and need to be \u201cremirrored\u201d?","text":"

    Mirroring in BNB Greenfield is based on the unique object ID and is not influenced by changes to object metadata, including its name. Even if an object is renamed, the mirroring process remains intact, as it is unaffected by such metadata modifications.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#can-the-mirrored-object-be-migrated-between-storage-providers","title":"Can the mirrored object be migrated between storage providers?","text":"

    The mirroring process in BNB Greenfield allows for object migration between storage providers because the object\u2019s data and metadata always reside on BNB Greenfield. As the data is not copied over to BSC, the mirroring remains unaffected. This means that migrating the actual content from one storage provider to another does not impact the mirroring process.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/","title":"Blob Hub","text":""},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#blob-hub-bnb-greenfield-as-data-archive-layer-for-evm-l1-chains","title":"Blob Hub: BNB Greenfield as Data Archive Layer for EVM L1 Chains","text":"

    The Greenfield community has recently launched \u201cBlobHub,\u201d a data archive layer designed for all layer 2 blockchains and Dapps which leverages EIP4844 blobs as data availability layer. All historical blobs can be persisted into Greenfield, and users can easily access these blobs whenever they want to query them. BlobHub not only serves Ethereum but also other blockchains that enable EIP4844.

    While each blob can be saved as an object in Greenfield, doing so individually would not be cost-effective. Thanks to the bundle service, which aggregates small files into one bundle for storage in Greenfield, this service can gather blobs from a wide range of blocks, validate their correctness, and upload them to Greenfield efficiently.

    Note: Greenfield will charge a fee for both storing and reading objects from the bucket owner. If there is not enough balance in the bucket payment account, users will be unable to query data until the quota is refilled.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#how-does-blob-hub-work","title":"How Does Blob Hub Work","text":"

    The Blob Hub primarily consists of two components: the blob-syncer and the api-server. To sync blobs to Greenfield, the blob-syncer service continuously fetches blobs from Ethereum and other blockchains and persists them in Greenfield. The api-server handles historical blob query requests from users. The bundle-service can aggregate blobs together, validate their correctness, and upload them to Greenfield efficiently.

    The syncing process ensures that no blob is missing and each blob synced to Greenfield is consistent. This is achieved by running a post-verification process that scans all uploaded blobs again, conducts integrity checks against data already stored in Greenfield, and detects any missing data. Duplicate uploads are prevented by key naming constraints in the Bundle service and Greenfield.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#who-needs-to-access-the-blob-hub","title":"Who Needs to Access the Blob Hub?","text":""},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#layer-2-node","title":"Layer 2 Node","text":"

    Layer 2 nodes that need to sync from the genesis block require access to historical block data via the Blob Hub. By leveraging Greenfield\u2019s robust infrastructure, they can rest assured that the integrity and availability of the stored data remain intact.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#analytical-platform","title":"Analytical Platform","text":"

    For on-chain data analytical builders, the blob hub service offers an alternative to centralized RPC service providers. By relying on a decentralized source, these builders gain access to a wealth of historical blob data without being tethered to centralized entities.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#query-blobs-from-blob-hub","title":"Query Blobs from Blob Hub","text":"

    Blob hub released its support to Ethereum and BSC now, it is going to support as many EVM chains as possible. The API is 100% compatible with the Beacon Chain and BSC API spec. Developers can get the supported network and endpoints in the doc.

    For more details about the API spec, please refer to BlobHub API

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#try-it-out","title":"Try It Out","text":"

    By adopting this innovative solution, stakeholders can ensure the integrity, accessibility, and longevity of blockchain data, thereby supporting a more resilient and transparent digital ecosystem. Don\u2019t miss the opportunity to revolutionize your data handling processes\u2014join the Greenfield community today and set a new standard for blockchain data reliability and security.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/","title":"BlockHub","text":""},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#blockhub","title":"BlockHub","text":"

    BlockHub offers a lightweight, trustless, and decentralized method for accessing blockchain data. It provides a user experience that is fully consistent with the original network\u2019s RPC and P2P access, eliminating the need for users to run full nodes or rely on centralized data providers to fetch block data. Don\u2019t want to trust a third party provider to provide the block data? Greenfield Blockhub is the answer. BlockHub is alive for BSC now.

    Much like Blob Hub, which uses the Bundle Service to archive blobs into a single bundle, BlockHub leverages the bundle service to combine a range of blocks into a single bundle. This approach optimizes storage usage, ensures cost-effectiveness, and maintains data integrity and accessibility.

    Note: Greenfield charges a fee for both storing and accessing objects. If the bucket owner\u2019s payment account lacks sufficient balance, users will be unable to query data until the quota is refilled.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#how-blockhub-operates","title":"How BlockHub Operates","text":"

    The BlockHub comprises three main components:

    The indexing process ensures data integrity by running a post-verification process. This process scans all uploaded blocks, conducts validation checks against data already stored in Greenfield, and detects any missing data.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#who-needs-to-access-the-blockhub","title":"Who Needs to Access the BlockHub?","text":""},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#node-operators","title":"Node Operators","text":"

    Node operators requiring full sync from the genesis block need access to historical block data via the BlockHub. Leveraging Greenfield\u2019s robust infrastructure, they can trust the integrity and availability of the stored data.

    The Greenfield community has launched the Greenfield Peer, a data-seed solution for those who need to run BSC nodes in fullsync mode. For more details, check out this page.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#data-analysts-and-researchers","title":"Data Analysts and Researchers","text":"

    BlockHub offers a valuable resource for data analysts and researchers who need comprehensive access to historical block data. By leveraging BlockHub, they can collect reliable data for analysis, research, and development purposes.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#accessing-block-data-with-blockhub","title":"Accessing Block Data with BlockHub","text":"

    BlockHub supports BSC now and its API is fully compatible with Ethereum API specifications, ensuring ease of integration for developers. Detailed information about supported networks and endpoints can be found in network and endpoints. For more details about the API spec, please refer to BlockHub API

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#try-it-out","title":"Try It Out","text":"

    Adopting this innovative solution ensures the integrity, accessibility, and longevity of blockchain data, supporting a more resilient and transparent digital ecosystem. Join the Greenfield community today and set a new standard for blockchain data reliability and security.

    "},{"location":"bnb-greenfield/for-developers/data-archive/data-archive-layer/","title":"Data Archive Layer","text":""},{"location":"bnb-greenfield/for-developers/data-archive/data-archive-layer/#what-is-data-archive-layer","title":"What Is Data Archive Layer?","text":"

    Modular blockchains divide the core functions of a classic blockchain into distinct specialized layers. Data availability layer is the essential component that ensures that transaction data included in each produced block is accessible to every node in the network.

    This layer essentially maintains the integrity and trust of the blockchain, allowing everyone to independently verify the validity of transactions. The data availability layer guarantees access to newly created data, but it does not provide access to the entire historical data. For example, EIP4844 and Celestica will discard blob data older than 18 days.

    The data archive layer is an extension of the data availability layer, ensuring that all historical block data remains publicly accessible after being archived.

    "},{"location":"bnb-greenfield/for-developers/data-archive/light-peer/","title":"Light Peer, a BSC data-seed By Greenfield","text":""},{"location":"bnb-greenfield/for-developers/data-archive/light-peer/#light-peer","title":"Light Peer","text":"

    With the launch of the block-hub, BSC historical block data is now accessible on Greenfield. For those operating BSC nodes in fullsync mode, connecting to the Light peer is a beneficial choice. The Light peer fetches block data from Greenfield and supplies it to BSC nodes via the P2P network.

    "},{"location":"bnb-greenfield/for-developers/data-archive/light-peer/#how-the-light-peer-works","title":"How The Light Peer Works","text":"

    The diagram below illustrates the functionality of the Light peer. While the Light peer does not participate in other operations within the BSC network, it solely provides block data to BSC nodes. It does not persist any data on its own; instead, when it receives requests (GetBodies and GetHeaders) from other BSC nodes, it fetches a bundle of blocks (# of blocks determined by the Block Indexer) from Greenfield and caches them in memory. This ensures the Light peer delivers block data to BSC nodes efficiently.

    "},{"location":"bnb-greenfield/for-developers/data-archive/light-peer/#how-to-interact-with-light-peer","title":"How to interact with Light Peer","text":"

    Utilizing the Light Peer is straightforward. Configure your BSC node to connect to the Light peer by adjusting the settings in your configuration file.

    Navigate to the P2P section of your BSC node configuration file and specify the enode info of the Light peer.

    # other configurations are omitted\n...\n[Node.P2P]\nMaxPeers = 1\nNoDiscovery = true\nTrustedNodes = []\nStaticNodes=[\"enode://a2c586f41d2cc6dc7445e32922305e92b4de7daad718744d12bf105a79715606330535cffae6a0d60c61567ff772796d906fcb72b9cbb578f10de3221bb34015@13.115.90.65:30303?discport=0\"]\n...\n
    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/","title":"RPC Endpoints - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#mainnet","title":"Mainnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#greenfield-chain-id-greenfield_1017-1","title":"Greenfield (chain-id: greenfield_1017-1)","text":"

    The above SPs are joined in the genesis state. For more SP endpoints, you can refer to GreenfieldScan SPs.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#bsc-chain-id-56","title":"BSC (chain-id: 56)","text":"

    You could find more endpoints from here.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#opbnb-chain-id-204","title":"opBNB (chain-id: 204)","text":"

    For more details, you can refer to here.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#blob-hub","title":"Blob hub","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#block-hub","title":"Block Hub","text":"

    Refer to the Block-Hub documentation for more details.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#testnet","title":"Testnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#greenfield-testnet-chain-id-greenfield_5600-1","title":"Greenfield Testnet (chain-id: greenfield_5600-1)","text":"

    The above SPs are joined in the genesis state. For more SP endpoints, you can refer to GreenfieldScan Testnet SPs.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#bsc-testnet-chain-id-97","title":"BSC Testnet (chain-id: 97)","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#opbnb-chain-id-5611","title":"opBNB (chain-id: 5611)","text":"

    For more details, you can refer to here.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#block-hub_1","title":"Block Hub","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/","title":"Network Info","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#network-information","title":"Network Information","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#rpc-endpoints","title":"RPC Endpoints","text":"

    The RPC Endpoints you may need to know to connect to Greenfield.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#bridge","title":"Bridge","text":"

    Greenfield and BSC account systems are fully compatible, using the same address format. This allows users to easily transfer their BNBs between Greenfield and BSC. The following cross-chain bridges are available.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#mainnet","title":"Mainnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#testnet","title":"Testnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#block-explorers","title":"Block Explorers","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#mainnet_1","title":"Mainnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#testnet_1","title":"Testnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#dcellar","title":"DCellar","text":"

    DCellar, as the inaugural application built on the BNB Greenfield, serves as an ultimate client of the BNB Greenfield network. Besides Basic file management and asset management functions, DCellar can also greatly assist developers in comprehending the functionalities of Greenfield:

    Here are the domain names for DCellar: - Mainnet: https://dcellar.io - Testnet: https://testnet.dcellar.io/

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#related-projects","title":"Related Projects","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#other","title":"Other","text":""},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/","title":"Basic File Management with CLI - BNB Greenfield Tutorials","text":""},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#introduction-to-file-management-with-cli","title":"Introduction to file management with CLI","text":""},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#introduction","title":"Introduction","text":"

    Backing up files is an essential practice for any development process. The benefits initially might not seem straightforward, but backups provide a safety net for disaster recovery, ensuring that data can be restored in the event of hardware failures, accidental deletions, or natural disasters.

    Backups often encompass local changes and experiments outside of the repository, ensuring that valuable work is not lost and can be integrated into the main codebase. Furthermore, repositories may not effectively handle non-code files and operational documentation, making backups crucial for their preservation. By providing redundancy and data integrity, backups reduce the risk of relying solely on a single repository. They also facilitate long-term archiving, ensuring access to historical data even if repository policies change or there is a switch to a different provider.

    Traditional cloud storage services, while convenient, are centralized and often have clauses in their terms and conditions that allow them to share your data with third parties and government agencies. This is where BNB Greenfield, a new decentralized storage on BNB Chain, comes in as a more secure and private alternative for backing up your files.

    In this tutorial, we will guide you through the process of setting up your environment, installing the necessary tools, and effectively backing up your files to BNB Greenfield, leveraging the benefits of decentralized storage while ensuring data security and ownership.

    We will also cover how to interact with the CLI tool, choose storage providers, manage your account balance, and manage buckets and uploaded files.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#setting-up-the-environment","title":"Setting Up the Environment","text":""},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#installation","title":"Installation","text":"

    Greenfield Command is a powerful command line to interact with Greenfield. To begin, you will need to install the BNB Greenfield command line tool follow the instruction from CLI github page.

    When running commands that interact with the greenfield, if there is no config/config.toml file under the path and the commands runs without \u201c\u2013config\u201d flag, the tool will generate the config/config.toml file automatically which is consistent with the network configuration under the path.

    Config file example will set up the necessary RPC address and chain id:

    MainnetTestnet
    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\nchainId = \"greenfield_1017-1\"\n
    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\nchainId = \"greenfield_5600-1\"\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#impport-account-and-generating-keystore","title":"Impport Account and Generating Keystore","text":"

    To set up your identity on the local machine and generate a keystore file, you will need to create the private file which will hold the identity private key. You can export your private key from MetaMask and write it into a local file as plaintext (You can select \u201cAccount Details\u201d from the dropdown menu of MetaMask. Click on the \u201cExport Private Key\u201d button at the bottom of the page. Once you have the files ready, run the following command \u201caccount import [keyfile]\u201d :

    // import key and generate a keystore file\n// key.txt indicates the private key file\ngnfd-cmd account import key.txt\n

    The terminal will prompt user to enter the password information. Users can also specify the password file path by using the \u201c\u2013passwordfile\u201d. While the password doesn\u2019t have any restriction on the length or complexity, it\u2019s better to follow generally recommended principles.

    This command will create a keystore file and store it in the path \u201ckeystore/key.json\u201d under the home directory of the system or the directory set by \u201c-home\u201d and will be picked up by the CLI for commands that require identity and payment. After generating the keystore file, make sure to delete the key.txt file with the private key inside.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#interacting-with-bnb-greenfield","title":"Interacting with BNB Greenfield","text":"

    BNB Greenfield is built on a distributed architecture where storage providers play a crucial role. The network consists of multiple storage providers that offer their resources to store and retrieve data from users. When using BNB Greenfield, users have the flexibility to choose which storage providers to utilize based on several factors, including price, terms and conditions, and network performance.

    When selecting storage providers, users can query the decentralized storage network through the CLI tool to obtain information about available providers. The list of providers will include their operator addresses and corresponding endpoints. Users can then analyze the providers based on the aforementioned factors and choose the ones that best align with their requirements.

    For the advanced use cases, users can diversify their storage across multiple providers to enhance redundancy and mitigate the risk of data loss. This approach distributes data among different providers, ensuring that even if one provider experiences issues, the data remains accessible from other providers. By carefully selecting storage providers based on price, terms and conditions, and network performance, users can optimize their decentralized storage experience and maintain control over their data while enjoying the benefits of enhanced security and privacy.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#selecting-storage-providers","title":"Selecting Storage Providers","text":"

    To query the network and get a list of storage providers, execute:

    ./gnfd-cmd sp ls\n

    The result should display a list of storage providers. For mainnet, there are several active storage providers, which can be used for development purposes.

    name     operator address                           endpoint                               status\nbnbchain 0x231099e40E1f98879C4126ef35D82FF006F24fF2 https://greenfield-sp.bnbchain.org:443 IN_SERVICE\ndefibit  0x05b1d420DcAd3aB51EDDE809D90E6e47B8dC9880 https://greenfield-sp.defibit.io:443   IN_SERVICE\nninicoin 0x2901FDdEF924f077Ec6811A4a6a1CB0F13858e8f https://greenfield-sp.ninicoin.io:443  IN_SERVICE\nnariox   0x88051F12AEaEC7d50058Fc20b275b388e15e2580 https://greenfield-sp.nariox.org:443   IN_SERVICE\nlumibot  0x3131865C8B61Bcb045ed756FBe50862fc23aB873 https://greenfield-sp.lumibot.org:443  IN_SERVICE\nvoltbot  0x6651ED78A4058d8A93CA4979b7AD516D1C9010ac https://greenfield-sp.voltbot.io:443   IN_SERVICE\nnodereal 0x03c0799AD70d19e723359E036a83E8f44f4B8Ba7 https://greenfield-sp.nodereal.io:443  IN_SERVICE\n

    The price for each storage provider can be checked using the operator address, for example:

    ./gnfd-cmd sp get-price 0x231099e40E1f98879C4126ef35D82FF006F24fF2\n

    The response will retrieve the price for reading the data, as well as for storing the data per second.

    get bucket read quota price: 0.1469890427  wei/byte\nget bucket storage price: 0.02183945725  wei/byte\nget bucket free quota: 1073741824\n

    To deduce the price for gigabytes (GB) per month from the metric of data usage in wei/byte, one needs to multiply the result by 0.002783138807808, as there are 1,073,741,824 bytes in 1 GB, 2,592,000 seconds in a month (30 days * 24 hours * 60 minutes * 60 seconds), and 10^18 wei in 1 BNB.

    The result will be the price for storing or transferring data in gigabytes per month, expressed in BNB. This calculation takes into account the rate of data usage and the duration of a month. Following the returned rate of wei/byte/sec, the converted amounts are:

    get bucket read quota price: 0.00041 BNB/GB/month\nget bucket storage price: 0.00006 BNB/GB/month\n

    Keep in mind that the pricing model and calculations may vary depending on the specific storage provider you are using. Always refer to the documentation or provider\u2019s information for accurate and up-to-date pricing details.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#account-management","title":"Account Management","text":"

    While BNB Smart Chain (BSC) and BNB Greenfield define their accounts in the same format, it\u2019s important to understand that they are two separate blockchains with distinct ledgers. As a result, users need to manage their balances separately on both BSC and BNB Greenfield blockchains.

    To transfer test BNB from the BSC to BNB Greenfield, users can utilize the dCellar application. By using the dCellar application, users can initiate the transfer process from their BSC address to their BNB Greenfield address.

    For testnet, users can acquire test BNB tokens for testing purposes by using a test faucet provided by BNB Greenfield which can be accessed at https://gnfd-bsc-faucet.bnbchain.org/. By visiting the faucet website, users can request a certain amount of test BNB tokens to be sent to their BSC testnet address.

    The balance can be checked using the following command:

    ./gnfd-cmd bank balance --address 0x14cfe3777565d942f7a3e1d1dcffd7945170c8fe\n

    And the result will be the current balance:

    balance: 10001464255952380934 weiBNB\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#object-operations","title":"Object Operations","text":"

    In BNB Greenfield objects and buckets are key components. Buckets are containers used to organize and manage data, while objects are the actual files stored within those buckets. Buckets serve as top-level storage units with unique names, and objects have unique identifiers within their respective buckets. Users can perform operations on objects, such as uploading, downloading, and deleting, while applying permissions and access controls at the bucket and object level. This structure allows for efficient storage, organization, and retrieval of data in a decentralized storage network.

    To create a bucket one need to call the following storage make-bucket command with the desired bucket name.

    ./gnfd-cmd bucket create gnfd://bucket123123123\n

    The operation will automatically choose a storage provider and submit a transaction to BNB Greenfield blockchain to write the associated metadata. Alternatively you can provide storage provider address, that is operator-address, if a specific provider should be used. The result should look something similar to the following:

    choose primary sp: https://greenfield-sp.bnbchain.org:443\ncreate bucket bucket123123123 succ, txn hash: 0x6c89316c5912cda8b69eac6e96aa644d374c39c635e07fae4297e03496e7726a\n

    As you can see, the result returns a transaction hash, which one can inspect using the block scanner, e.g. https://greenfieldscan.com. Going to https://greenfieldscan.com/tx/0x6c89316c5912cda8b69eac6e96aa644d374c39c635e07fae4297e03496e7726a, will show all the details of the transaction.

    Notice that we in the details we can see the bucket owner details, moi; primary storage provider address, and the payment address. Since we haven\u2019t created a separate payment account, our default account will serve as the payment account as well.

    With regards to the storage provider address, if you remember, it was picked for us automatically as https://greenfield-sp.bnbchain.org:443. And from Selecting Storage Providers section we can see that its address is indeed 0x231099e40E1f98879C4126ef35D82FF006F24fF2.

    Lastly, it\u2019s time to upload a file, but before we upload anything, let\u2019s create one with a sample text using the echo command as follows:

    echo 'Random sample text' > test4.txt\n

    Finally to upload the file to our newly created bucket bucket123123123, one needs to execute the following command:

    ./gnfd-cmd object put  --contentType \"text/xml\" --visibility private ./test4.txt  gnfd://bucket123123123/test4.txt\n
    Notice that we\u2019ve provided the visibility flag and made the file private. The successful result should be similar to the following:
    create object test4.txt on chain finish, txn Hash: 0x5a885b7da8e8eb6921c84540d29b385b2dcee1f5ebdb4bb6c9219cf82e6ca80d\nput object test4.txt successfully \n

    Similarly, going to https://greenfieldscan.com/tx/0x5a885b7da8e8eb6921c84540d29b385b2dcee1f5ebdb4bb6c9219cf82e6ca80d will show the details of the file upload. Here, observe the transaction payload and scroll to the \u201cvisibility\u201d attribute, which confirms the privacy status.

    {\"key\":\"visibility\" \"value\":\"\\\"VISIBILITY_TYPE_PRIVATE\\\"\" }\n

    After successfully uploading the file, let\u2019s verify the content of the file and compare it to the one we\u2019ve uploaded - they should be identical.

    ./gnfd-cmd object get gnfd://bucket123123123/test4.txt ./test4-copy.txt\n

    The operation will download the file and output the length of the file, as follows:

    download object test4.txt successfully, the file path is ./test4-copy.txt, content length:19\n

    If you know the sp endpoint that object belongs to, you can optimize the download speed by add \u2013spEndpoint flag to download cmd, such as:

    ./gnfd-cmd object get --spEndpoint https://gnfd-testnet-sp3.nodereal.io gnfd://bucket123123123/test4.txt ./test4-copy.txt\n

    To validate the integrity of the file, we can compare its content to the originally uploaded one. Empty output confirms there are no differences.

    diff test4.txt test4-copy.txt \n
    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#upload-multiple-objects","title":"Upload multiple objects","text":"

    gnfd-cmd also support uploads all files from a folder recursively.

    Let\u2019s say that there is a folder called website where you store all the files for your website.

    $ ls\nindex.html  plato.jpeg  styles.css\n
    To upload all these files into your bucket, you can run the following commands:
    gnfd-cmd object put --recursive ./website gnfd://ylatitsb\n

    Please note that --recursive is used to put all files or objects under the specified directory or prefix in a recursive way. The default value is false

    The successful result should be similar to the following:

    ================================================\nYour batch upload is submitted as a task, task ID is sdgerdf-sfdgasg-1237hedfg\nYou can check your task status and progress by using cmd as below:\n\n- List all your tasks: ./gnfd-cmd task ls\n- Check status: ./gnfd-cmd task status --task.id taskID\n- Retry (in case this process is killed accidentally): ./gnfd-cmd task retry --task.id taskID\n- Delete task: ...\n\n>>================================================\nUpload Task building\n\nsealed index.html\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#task-operations","title":"Task Operations","text":"

    When object put \u2013recursive is used, tasks are automatically created

    You can view/retry/delete tasks with gnfd-cmd task

    Using the gnfd-cmd task requires a new session to be opened while the gfnd-cmd object put --recursive is in progress. If the current session is interrupted, the put object is interrupted

    ./build/gnfd-cmd task  status --taskId abe92a9a-1aa0-45be-9e0b-4cd400c38a06\n
    Viewing Task status taskId will be generated after the gfnd-cmd object put --recursive
    Folder: ./website\nStatus: created\nsealed            index.html\nwait_for_upload   styles.css\n
    ./build/gnfd-cmd task  retry --taskId abe92a9a-1aa0-45be-9e0b-4cd400c38a06\n

    gfnd-cmd object put --recursive will be used to retry after a failure or interruption

    task: abe92a9a-1aa0-45be-9e0b-4cd400c38a06\nfolder name: ./website\nretrying...\n\nsealed index.html\n

    ./build/gnfd-cmd task  delete --taskId abe92a9a-1aa0-45be-9e0b-4cd400c38a06\n
    You can delete a task by deleting it

    You can go to GreenfieldScan to view the change of your bucket.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#conclusion","title":"Conclusion","text":"

    Overall, backups during software development offer peace of mind, efficient recovery, and safeguarding of the project\u2019s integrity. They minimize downtime and prevent significant setbacks.

    After gaining familiarity with the command line tool and BNB Greenfield through this tutorial, the next step is to explore and experiment with creating files, buckets, and permission groups. By creating multiple files and organizing them into buckets, users can gain hands-on experience with the storage capabilities of BNB Greenfield.

    It is highly recommended for users to engage in hands-on exploration by trying out different wallets and understanding the basic operations and permissioning mechanisms. This will provide a deeper understanding of how BNB Greenfield functions and how to effectively manage and secure data within the decentralized storage system.

    This practical experience will pave the way for comprehending more advanced topics discussed in future articles, such as programmability and BNB Greenfield\u2019s innovative concept of flow-based billing and asset monetization. By exploring the diverse functionalities and experimenting with different configurations, users can unlock the full potential of BNB Greenfield and unlock its new data economy concepts.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/","title":"Hosting a Website on Greenfield - BNB Greenfield Tutorials","text":""},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#creating-and-uploading-a-website-with-cli","title":"Creating and uploading a website with CLI","text":""},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#introduction","title":"Introduction","text":"

    In today\u2019s era, having a website has become essential for individuals and businesses alike. With advancements in AI, tools like ChatGPT and Bard can help create a simple website or boilerplate with just a few sentences. This tutorial will guide you through the process of creating and uploading a website to BNB Greenfield, a decentralized storage on the BNB Chain.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#creating-a-website","title":"Creating a website","text":"

    A website typically consists of HTML pages, CSS stylesheets, and JavaScript scripts for enhanced interactivity. These files work together to create the visual layout, design, and functionality of the website. Go to the AI tool of your choice and type something like \u201cCreate a website about Plato\u2019s biography with images\u201d. And ideally, after a few iterations, you\u2019ll get to a decent-looking website.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#deploying-a-website","title":"Deploying a website","text":"

    Deploying a website to a web hosting platform is crucial because it makes the website publicly accessible and ensures its availability to users. When a website is hosted on a cloud server it becomes accessible to anyone with an internet connection. Users can access the website by typing its URL or domain name into a web browser.

    In the case of BNB Greenfield, the decentralized network of storage providers contributes to increased availability by distributing the website\u2019s files across multiple nodes. Additionally, decentralized networks like BNB Greenfield provide data redundancy by storing multiple copies of the website\u2019s files on different nodes, reducing the risk of data loss. BNB Greenfield prioritizes security measures to protect websites and their data from unauthorized access, cyber threats, and data breaches.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#creating-a-bucket","title":"Creating a Bucket","text":"

    To start, create a separate bucket for your website on BNB Greenfield using the following command:

    ./gnfd-cmd bucket create --visibility=public-read gnfd://my-plato-website --primarySP 0x231099e40E1f98879C4126ef35D82FF006F24fF2\n

    The example return message is like the following:

    make_bucket: my-plato-website\ntransaction hash:  E083FB2647D0A53640B63AD1DB8EFA0E1C5CC05454C0774E3DB2A4822E73D423\n

    You can verify the transaction in explorer here.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#uploading-supporting-files","title":"Uploading Supporting Files","text":"

    Next, upload the stylesheet and image files to your newly created bucket. Set the visibility flag as public-read to make the files accessible to everyone:

    ./gnfd-cmd object put --visibility=public-read ./plato.jpg gnfd://my-plato-website/plato.jpg ./gnfd-cmd object put --visibility=public-read ./styles.css gnfd://my-plato-website/styles.css\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#bnb-greenfield-url","title":"BNB Greenfield Url","text":"

    BNB Greenfield utilizes a specific URL format known as the BNB Greenfield Url to identify and access objects within its decentralized storage. The URL format follows the pattern: gnfd://<bucket_name><object_name>?[parameter]*.

    Let\u2019s break down the components of this format:

    1. \u201cgnfd://\u201d - This is the fixed leading identifier that indicates the URL is associated with BNB Greenfield. It is mandatory and serves as a marker for Greenfield URLs.

    2. bucket_name - Refers to the name of the bucket where the object is stored. It is a mandatory component and helps identify the specific storage location within BNB Greenfield.

    3. object_name - Represents the name of the object (e.g., file) within the bucket. It is also mandatory and allows for precise identification of the desired resource.

    4. parameter - This component is optional and consists of a list of key-value pairs. Parameters provide additional information for the URI, enabling customization or specific functionality. Examples of parameters could include cache settings or other metadata.

    Additionally, BNB Greenfield allows Service Providers (SPs) to register multiple endpoints for accessing their services. For instance, an SP named \u201cSP1\u201d might request users to download objects via a URL like https://greenfield.sp1.com/download. The complete RESTful API for downloading an object from \u201cSP1\u201d would resemble: https://greenfield.sp1.com/download/mybucket/myobject.jpg, where \u201cmybucket\u201d is the bucket name and \u201cmyobject.jpg\u201d is the specific object within that bucket.

    In the context of our website, the bucket was created under the SP2 service provider, and the serving endpoint for accessing the website\u2019s content is https://gnfd-testnet-sp-2.bnbchain.org/. This endpoint allows users to access the website\u2019s files, such as HTML, CSS, images, and more, stored within the designated bucket on BNB Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#updating-the-references","title":"Updating the references","text":"

    Once the supporting files are uploaded, update the links in your HTML file to point to the correct URLs. Following the BNB Greenfield Url pattern, we need to update the URLs in our index.html file to ensure correct file retrieval.

    For example, if we had an image file named plato.jpg located in the \u201cimages\u201d directory, previously the URL reference would be \u201cimages/plato.jpg\u201d. However, with BNB Greenfield\u2019s URL format, we need to modify it to include the serving endpoint and the specific bucket name.

    Instead of \u201cimages/plato.jpg\u201d, we would change it to https://gnfd-testnet-sp-2.bnbchain.org/view/my-plato-website/images/plato.jpg, where \u201cmy-plato-website\u201d corresponds to the bucket name in which the file is stored. This updated URL ensures that the browser can retrieve the correct image file from BNB Greenfield.

    But things get better! Since the BNB Greenfield URL format remains identical for all files within the same bucket, we can simplify the URLs for files residing within the same bucket. In the case of the CSS file, we can reference it using a relative path without specifying the full URL. For example:

    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">\n

    Similarly, for the image file plato.jpg, we can use a relative path without the need to specify the full URL:

    <img src=\"plato.jpg\" alt=\"Plato\" class=\"plato-image\">\n

    By using relative paths, the browser will correctly fetch the CSS file and the image file from the same bucket within BNB Greenfield, eliminating the need to include the full path in these specific cases.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#uploading-html-files","title":"Uploading HTML Files","text":"

    Upload the modified index.html file to your bucket using the following command:

    ./gnfd-cmd object put --visibility=public-read --contentType=text/html ./index.html \ngnfd://my-plato-website/index.html \n

    Example output:

    object index.html created on chain\ntransaction hash:  20921F3C1DBE3F911217CE82BDC9DC2A745AF61912651A5F9D80F10989A8FC20\n\nsealing...\nupload index.html to gnfd://my-plato-website/index.html\n

    Now, let\u2019s eagerly click the link to view our brand new website at https://gnfd-testnet-sp1.bnbchain.org/view/my-plato-website/index.html and feel the anticipation building up.

    \ud83e\udd41Drum beat\u2026

    But, oh no! Something went awry. Instead of the website loading, the file started downloading automatically. Frustration sets in, and I embarked on a lengthy debugging journey, spending a good hour trying to figure out the issue.

    Finally, I discovered the culprit: we forgot to specify the content type for the files, making them unrecognizable and causing them to be downloaded instead of served.

    However, let\u2019s not forget that BNB Greenfield is an immutable storage. So to update the file, we must first delete it and then reupload it.

    To accomplish this, I used the power of the \u2018object delete\u2019 command:

    ./gnfd-cmd object rm gnfd://my-plato-website/index.html\n

    Wait for the confirmation that the file was successfully deleted, accompanied by a transaction hash: 4B12BCF26525C1B661389529524DF14E23164D000FA47FB2E0D0BE26B131E04A.

    And reupload the html file, this time accompanied by the content-type flag:

    ./gnfd-cmd object put --visibility=public-read --contentType=text/html ./index.html gnfd://my-plato-website/index.html\n

    \ud83e\udd41\ud83e\udd41Drum beat intensifies\u2026

    Oh, no! The website still looks horrendous, and worse yet, the image of Plato is nowhere to be found. Frustration turned into disappointment as we discovered that the browser was throwing an error due to an incorrect MIME type. It refused to apply the styles from https://gnfd-testnet-sp-2.bnbchain.org/view/my-plato-website/styles.css because the MIME type was set as \u2018text/plain\u2019, which is not a supported stylesheet MIME type when strict MIME checking is enabled. Fear not! The error looks familiar and we already know exactly what needed to be done. So swiftly deleting the problematic files and reuploading them correctly this time:

    ./gnfd-cmd object rm gnfd://my-plato-website/plato.jpg\n./gnfd-cmd object rm gnfd://my-plato-website/styles.css\n
    And then, with a determined spirit:
    ./gnfd-cmd object put --visibility=public-read --contentType=image/jpeg ./plato.jpg gnfd://my-plato-website/plato.jpg \n./gnfd-cmd object put --visibility=public-read --contentType=text/css ./styles.css gnfd://my-plato-website/styles.css\n

    \ud83e\udd41\ud83e\udd41\ud83e\udd41Drum beat crescendos\u2026

    And finally, we heard the triumphant sound of trumpets!

    However, as we gaze upon the site, we can\u2019t help but admit that it doesn\u2019t look particularly astonishing. It falls short of our grandest expectations. Yet, considering that we generated and uploaded it in just a matter of minutes, it\u2019s still a decent outcome given our investment of time and effort.

    The content and image look good though, it just needs more love with styling\u2026but that\u2019s a story for another tutorial.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#conclusion","title":"Conclusion","text":"

    Our journey with website development has been filled with ups and downs. We encountered challenges along the way, but with perseverance and a little debugging, we managed to deploy our website successfully.

    BNB Greenfield\u2019s URL format and immutable storage principles require to be mindful of content types and careful when updating files. Despite the minor setbacks, BNB Greenfield remains a valuable platform for deploying websites, offering increased availability, reliability, and quite easy command tools.

    Hope you enjoyed it and looking forward to see your websites on BNB Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/","title":"Overview - BNB Greenfield Tutorials","text":""},{"location":"bnb-greenfield/for-developers/tutorials/overview/#overview-building-decentralized-applications-dapps-with-bnb-greenfield","title":"Overview: Building Decentralized Applications (dApps) with BNB Greenfield","text":"

    In this section, we will introduce the two main methods for developing dApps on BNB Greenfield: using smart contracts deployed to BNB Smart Chain (BSC) and interacting directly with BNB Greenfield through our Software Development Kit (SDK) or Command Line Interface (CLI).

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#data-marketplace-demo","title":"Data Marketplace Demo","text":"

    Data marketplace is a data exchange platform where users can freely create, list, trade, and sell data assets, including digital publications, scientific experimental data, and specific domain data.

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#demo-link","title":"Demo Link","text":""},{"location":"bnb-greenfield/for-developers/tutorials/overview/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/overview/#developing-with-smart-contracts-on-bsc","title":"Developing with smart contracts on BSC","text":"

    One of the primary methods for building dApps with BNB Greenfield is by deploying smart contracts to the BSC. Smart contracts are self-executing programs that facilitate and enforce the execution of agreements without the need for intermediaries.

    In this section, we will guide you through the process of creating, deploying, and interacting with smart contracts on BSC using popular development frameworks like Solidity and Truffle. You can find detailed tutorials and examples for developing dApps using smart contracts in the Building Smart Contract dApps section.

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#interacting-with-bnb-greenfield-through-sdk-and-cli","title":"Interacting with BNB Greenfield through SDK and CLI","text":"

    BNB Greenfield offers two native application options for interacting with the platform without involving the development of smart contracts:

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#software-development-kit-sdk","title":"Software Development Kit (SDK)","text":"

    The Software Development Kit (SDK) is a powerful set of tools, libraries, and APIs that enable seamless integration with BNB Greenfield\u2019s decentralized storage system. The SDK allows you to build dApps using only the SDK functionalities, without the need to develop smart contracts. With the SDK, you can store and retrieve data, manage access controls, and handle encryption to ensure the privacy and security of your dApp\u2019s data.

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#command-line-interface-cli","title":"Command Line Interface (CLI)","text":"

    The Command Line Interface (CLI) is another native application provided by BNB Greenfield, allowing you to interact with the platform directly from the terminal. The CLI provides various commands to perform essential tasks efficiently, such as uploading files, managing data permissions, and monitoring storage usage. As with the SDK, using the CLI does not involve the development of smart contracts.

    In the following sections, we will delve deeper into each native application, providing step-by-step guides, code snippets, and best practices to empower you to create powerful and innovative dApps without the need for smart contract development.

    You can find more information and detailed instructions in the Building Native dApps section.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/","title":"How to transition from S3 to Greenfield - BNB Greenfield Develop","text":""},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#how-to-transition-from-s3-to-greenfield","title":"How to transition from S3 to Greenfield","text":""},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#introduction","title":"Introduction","text":"

    Greenfield is a blockchain-based decentralized storage solution designed to enhance the decentralization of data ownership and management, allowing users to manage their own data and assets. This platform promotes the development of decentralized applications (dApps) by offering on-chain data permission management and APIs similar to those of Web2, enhancing data security and management capabilities through the introduction of Storage Providers (SPs), which are responsible for providing authentication and storage services.

    In terms of permission management, SPs offer a range of authentication services. Unlike AWS S3, which control user permissions through AWS Keys and AWS Secrets, SPs in Greenfield use private keys for permission control. This means that on the Greenfield platform, permission authentication is reliant on blockchain technology, ensuring security and decentralization, while also extending blockchain functionalities, including permission authentication and data storage capabilities.

    In Greenfield\u2019s design, users have the freedom to select any SP as their Primary SP, along with additional SPs as Secondary SPs, ensuring both performance and reliability in object storage. Primary SPs are primarily responsible for storing all data segments of an object and directly responding to user read or download requests, whereas Secondary SPs store data blocks generated by Erasure Coding (EC) technology, helping to improve data availability.

    Compared to AWS S3, Greenfield\u2019s distributed storage structure not only enhances data durability and recoverability but also ensures data integrity and verifiability using blockchain technology. Through this approach, Greenfield is committed to promoting a new data economy and dApp model construction, improving the transparency and efficiency of data management, and realizing data decentralization management and ownership proof through blockchain technology.

    We will now showcase on the SDK through Greenfield and AWS S3.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#init-sdk-client","title":"Init SDK client","text":"

    S3

    const (\n    AWSKey          = \"mock-aws-key\"\n    AWSSecret       = \"mock-aws-secret\"\n    Region          = \"us-east-1\"\n)\n\ncfg, err := config.LoadDefaultConfig(context.TODO(),\n    config.WithRegion(Region),\n    config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(AWSKey, AWSSecret, \"\")),\n)\nhandleErr(err, \"LoadDefaultConfig\")\nclient := s3.NewFromConfig(cfg)\n

    For AWS S3, the initialization uses the AWS Key and AWS Secret to create an AWS S3 client to allow user interaction. The Region specifies the region where the user\u2019s bucket is located.

    Greenfield

    const (\n    RpcAddr         = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\" // Greenfield Testnet RPC Address\n    ChainId         = \"greenfield_5600-1\" // Greenfield Testnet Chain ID\n    PrivateKey      = \"mock-private-key\"\n)\nclient, primarySP, err := NewFromConfig(ChainId, RpcAddr, PrivateKey)\nhandleErr(err, \"NewFromConfig\")\n

    For Greenfield, the RPC Address and Chain ID are used to select the specific Greenfield network, with the example above being for the Testnet. Users need to interact using a private key exported from their wallet.

    Greenfield Mainnet Chain ID: greenfield_1017-1

    Greenfield Mainnet RPC

    https://greenfield-chain.bnbchain.org:443

    https://greenfield-chain-ap.bnbchain.org:443

    https://greenfield-chain-eu.bnbchain.org:443

    https://greenfield-chain-us.bnbchain.org:443

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#create-bucket","title":"Create bucket","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\n_, err = client.CreateBucket(context.TODO(), &s3.CreateBucketInput{\n    Bucket: aws.String(BucketName),\n})\nhandleErr(err, \"CreateBucket\")\n

    In AWS S3, the CreateBucket method is called with a configuration object specifying the bucket name. The operation is straightforward, reflecting S3\u2019s cloud storage focus, where the primary concern is the creation and management of storage containers in the cloud.

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\n_, err = client.CreateBucket(context.TODO(), BucketName, primarySP, types.CreateBucketOptions{})\nhandleErr(err, \"CreateBucket\")\n

    For Greenfield, the CreateBucket method also requires a bucket name but includes additional parameters like primarySP, which is obtained during client initialization. The primarySP plays a crucial role in executing and storing corresponding bucket data, indicating a more complex interaction pattern likely due to the blockchain-based nature of Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#list-buckets","title":"List buckets","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\nbucketsList, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})\nhandleErr(err, \"ListBuckets\")\nfor _, bucket := range bucketsList.Buckets {\n    fmt.Printf(\"* %s\\n\", aws.ToString(bucket.Name))\n}\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\nbucketsList, err := client.ListBuckets(context.TODO(), types.ListBucketsOptions{})\nhandleErr(err, \"ListBuckets\")\nfor _, bucket := range bucketsList.Buckets {\n    fmt.Printf(\"* %s\\n\", bucket.BucketInfo.BucketName)\n}\n

    During the initialization of the client for both systems, user information is already obtained, allowing for the return of corresponding buckets through a User object. This process indicates that transitioning from AWS S3 to Greenfield can be achieved with minimal effort and cost.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#delete-bucket","title":"Delete bucket","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\n_, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{\n    Bucket: aws.String(BucketName),\n})\nhandleErr(err, \"Delete Bucket\")\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\n_, err = cli.DeleteBucket(context.TODO(), BucketName, types.DeleteBucketOption{})\nhandleErr(err, \"Delete Bucket\")\n

    The process of deleting a bucket in both AWS S3 and Greenfield is essentially identical, allowing users to easily delete a bucket by simply using its name.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#create-object","title":"Create object","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\n_, err = client.PutObject(context.TODO(), &s3.PutObjectInput{\n    Bucket: aws.String(BucketName),\n    Key:    aws.String(ObjectKey),\n    Body:   file,\n    })\nhandleErr(err, \"PutObject\")\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\ntxnHash, err := cli.CreateObject(context.TODO(), BucketName, ObjectKey, file, types.CreateObjectOptions{})\nhandleErr(err, \"CreateObject\")\n\nerr = cli.PutObject(context.TODO(), BucketName, ObjectKey, int64(fileInfo.Size()),\nfile, types.PutObjectOptions{TxnHash: txnHash})\nhandleErr(err, \"PutObject\")\n

    In the process of creating objects, there is a difference between Greenfield and S3. In Greenfield, it is necessary to first create the object before performing the put object operation. This is because Greenfield requires users to create metadata on the Greenfield blockchain before submitting object to the SP, in order to ensure the integrity of the object.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#list-objects","title":"List objects","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\nobjects, err := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{\n    Bucket: aws.String(BucketName),\n})\nhandleErr(err, \"ListObjectsV2\")\nfor _, item := range objects.Contents {\n    fmt.Printf(\"* %s\\n\", aws.ToString(item.Key))\n}\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\nobjects, err := cli.ListObjects(context.TODO(), BucketName, types.ListObjectsOptions{\n})\nhandleErr(err, \"ListObjects\")\nfor _, obj := range objects.Objects {\n    log.Printf(\"* %s\\n\", obj.ObjectInfo.ObjectName)\n}\n

    In both AWS S3 and Greenfield, retrieving all objects within a bucket can be easily accomplished by simply using the bucket\u2019s name. This functionality indicates a user-friendly approach to data management, allowing users to efficiently access and manage the contents of their storage without the need for intricate query parameters or complex configuration.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#delete-object","title":"Delete object","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\n_, err = client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{\n    Bucket: aws.String(BucketName),\n    Key:    aws.String(ObjectKey),\n})\nhandleErr(err, \"Delete Object\")\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\n_, err = cli.DeleteObject(context.TODO(), BucketName, ObjectKey, types.DeleteObjectOption{})\nhandleErr(err, \"Delete Object\")\n

    Deleting an object in both AWS S3 and Greenfield is fundamentally similar, enabling users to effortlessly remove an object by specifying both the bucket name and the object name.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#get-object","title":"Get Object","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\nresp, err := client.GetObject(context.TODO(), &s3.GetObjectInput{\n    Bucket: aws.String(BucketName),\n    Key:    aws.String(ObjectKey),\n})\nhandleErr(err, \"GetObject\")\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\nresp, _, err := cli.GetObject(context.TODO(), BucketName, ObjectKey, types.GetObjectOptions{})\nhandleErr(err, \"GetObject\")\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#summary","title":"Summary","text":"

    AWS S3 and Greenfield offer streamlined data retrieval processes, with users specifying bucket and object names for efficient access. While AWS S3 relies on key-pair authentication and region specification for data locality and access efficiency, Greenfield adopts a blockchain-based approach, using private keys for authentication and RPC Addresses along with Chain IDs for network connectivity. Greenfield enhances service quality through regional RPC endpoints, allowing users to choose the most efficient connection based on their location.

    The structural similarity in SDKs for operations like bucket creation is notable, with Greenfield requiring an additional step to obtain a primarySP during client initialization. This minimal difference suggests a smooth transition for S3 users to Greenfield, highlighting the ease of adaptation due to familiar SDK code structures and metadata handling. Moreover, Greenfield introduces a two-step object management process, offering greater control over object lifecycle states than S3\u2019s more straightforward approach. Despite this, the core functionalities remain similar, ensuring that S3 users can quickly adapt to Greenfield\u2019s environment without significant hurdles.

    Overall, the transition from AWS S3 to Greenfield is facilitated by similar SDK coding practices and metadata management approaches, making it accessible for users familiar with S3 to migrate to Greenfield\u2019s blockchain-based storage solution with minimal learning curve. This compatibility underscores the potential for seamless adaptation, leveraging existing cloud storage knowledge while navigating the nuances of blockchain technology.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#attached-code","title":"Attached code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#example-of-greenfield-integration","title":"Example of Greenfield Integration","text":"
    package main\n\nimport (\n    \"bytes\"\n    \"context\"\n    \"fmt\"\n    \"io\"\n    \"log\"\n    \"os\"\n    \"time\"\n\n    \"github.com/bnb-chain/greenfield-go-sdk/client\"\n    \"github.com/bnb-chain/greenfield-go-sdk/types\"\n)\n\n// The config information is consistent with the testnet of greenfield\n// You need to set the privateKey, bucketName, objectName and groupName to make the basic examples work well\nconst (\n    RpcAddr         = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n    ChainId         = \"greenfield_5600-1\"\n    PrivateKey      = \"mock-private-key\"\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"api.js\"\n    UploadObjectKey = \"test-api.js\"\n    DownloadPath    = \"/Users/Desktop/s3test/\"\n    UploadPath      = \"/Users/Desktop/s3test/\"\n)\n\nfunc main() {\n    cli, primarySP, err := NewFromConfig(ChainId, RpcAddr, PrivateKey)\n    handleErr(err, \"NewFromConfig\")\n\n    // create bucket\n    _, err = cli.CreateBucket(context.TODO(), BucketName, primarySP, types.CreateBucketOptions{})\n    handleErr(err, \"CreateBucket\")\n\n    // list buckets\n    bucketsList, err := cli.ListBuckets(context.TODO(), types.ListBucketsOptions {\n        ShowRemovedBucket: false,\n    })\n    handleErr(err, \"ListBuckets\")\n    for _, bucket := range bucketsList.Buckets {\n        fmt.Printf(\"* %s\\n\", bucket.BucketInfo.BucketName)\n    }\n\n    // create object\n    file, err := os.Open(UploadPath + UploadObjectKey)\n    handleErr(err, \"PutObject\")\n    defer file.Close()\n\n    fileInfo, err := file.Stat()\n    handleErr(err, \"Stat\")\n\n    // create object\n    txnHash, err := cli.CreateObject(context.TODO(), BucketName, UploadObjectKey, file, types.CreateObjectOptions{})\n    handleErr(err, \"CreateObject\")\n\n    var buf bytes.Buffer\n    _, err = io.Copy(&buf, file)\n\n    // put object\n    err = cli.PutObject(context.TODO(), BucketName, UploadObjectKey, int64(fileInfo.Size()),\n    file, types.PutObjectOptions{TxnHash: txnHash})\n    handleErr(err, \"PutObject\")\n\n    // wait for object having been successfully uploaded\n    time.Sleep(10 * time.Second)\n\n    // list objects\n    objects, err := cli.ListObjects(context.TODO(), BucketName, types.ListObjectsOptions {\n        ShowRemovedObject: false, Delimiter: \"\", MaxKeys: 100, SPAddress: \"\",\n    })\n    handleErr(err, \"ListObjects\")\n    for _, obj := range objects.Objects {\n        log.Printf(\"* %s\\n\", obj.ObjectInfo.ObjectName)\n    }\n\n    // get object\n    reader, _, err := cli.GetObject(context.TODO(), BucketName, UploadObjectKey, types.GetObjectOptions{})\n    handleErr(err, \"GetObject\")\n\n    outFile, err := os.Create(DownloadPath + ObjectKey)\n    handleErr(err, \"DownloadObject\")\n    defer outFile.Close()\n\n    _, err = io.Copy(outFile, reader)\n    handleErr(err, \"DownloadObject\")\n}\n\nfunc NewFromConfig(chainID, rpcAddress, privateKeyStr string) (client.IClient, string, error) {\n    account, err := types.NewAccountFromPrivateKey(\"test\", privateKeyStr)\n    if err != nil {\n        log.Fatalf(\"New account from private key error, %v\", err)\n        return nil, \"\", err\n    }\n\n    cli, err := client.New(chainID, rpcAddress, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n        return nil, \"\", err\n    }\n    ctx := context.Background()\n\n    // get storage providers list\n    spLists, err := cli.ListStorageProviders(ctx, true)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n        return nil, \"\", err\n    }\n    // choose the first sp to be the primary SP\n    primarySP := spLists[0].GetOperatorAddress()\n    return cli, primarySP, nil\n}\n\nfunc handleErr(err error, funcName string) {\n    if err != nil {\n        log.Fatalln(\"fail to \" + funcName + \": \" + err.Error())\n    }\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#example-of-s3-integration","title":"Example of S3 Integration","text":"
    package main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"io\"\n    \"log\"\n    \"os\"\n    \"time\"\n\n    \"github.com/aws/aws-sdk-go-v2/aws\"\n    \"github.com/aws/aws-sdk-go-v2/config\"\n    \"github.com/aws/aws-sdk-go-v2/credentials\"\n    \"github.com/aws/aws-sdk-go-v2/service/s3\"\n)\n\nconst (\n    AWSKey          = \"mock-aws-key\"\n    AWSSecret       = \"mock-aws-secret\"\n    Region          = \"us-east-1\"\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"mock-object-name\"\n    UploadObjectKey = \"test-api.js\"\n    DownloadPath    = \"/Users/Desktop/s3test/\"\n    UploadPath      = \"/Users/Desktop/s3test/\"\n)\n\nfunc main() {\n    // set up aws s3 config\n    cfg, err := config.LoadDefaultConfig(context.TODO(),\n        config.WithRegion(Region),\n        config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(AWSKey, AWSSecret, \"\")),\n    )\n    handleErr(err, \"LoadDefaultConfig\")\n    client := s3.NewFromConfig(cfg)\n\n    // create bucket\n    _, err = client.CreateBucket(context.TODO(), &s3.CreateBucketInput {\n        Bucket: aws.String(BucketName),\n    })\n    handleErr(err, \"CreateBucket\")\n\n    // list buckets by owner\n    result, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})\n    handleErr(err, \"ListBuckets\")\n    for _, bucket := range result.Buckets {\n        fmt.Printf(\"* %s\\n\", aws.ToString(bucket.Name))\n    }\n\n    // create object\n    file, err := os.Open(UploadPath + UploadObjectKey)\n    handleErr(err, \"PutObject\")\n    defer file.Close()\n\n    _, err = client.PutObject(context.TODO(), &s3.PutObjectInput {\n        Bucket: aws.String(BucketName),\n        Key:    aws.String(UploadObjectKey),\n        Body:   file,\n    })\n    handleErr(err, \"PutObject\")\n\n    // wait for object having been successfully uploaded\n    time.Sleep(10 * time.Second)\n    objects, err := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input {\n        Bucket: aws.String(BucketName),\n    })\n    handleErr(err, \"ListObjectsV2\")\n    for _, item := range objects.Contents {\n        fmt.Printf(\"* %s\\n\", aws.ToString(item.Key))\n    }\n\n    // download object\n    resp, err := client.GetObject(context.TODO(), &s3.GetObjectInput {\n        Bucket: aws.String(BucketName),\n        Key:    aws.String(UploadObjectKey),\n    })\n    handleErr(err, \"DownloadObject\")\n\n    defer resp.Body.Close()\n\n    outFile, err := os.Create(DownloadPath + ObjectKey)\n    handleErr(err, \"DownloadObject\")\n\n    defer outFile.Close()\n\n    _, err = io.Copy(outFile, resp.Body)\n    handleErr(err, \"DownloadObject\")\n\n    _, err = client.DeleteObject(context.TODO(), &s3.DeleteObjectInput {\n        Bucket: aws.String(BucketName),\n        Key:    aws.String(ObjectKey),\n    })\n    handleErr(err, \"Delete Object\")\n\n    _, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput {\n        Bucket: aws.String(BucketName),\n    })\n    handleErr(err, \"Delete Bucket\")\n}\n\nfunc handleErr(err error, funcName string) {\n    if err != nil {\n        log.Fatalln(\"fail to \" + funcName + \": \" + err.Error())\n    }\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/","title":"Native Access Control - BNB Greenfield Access Control","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#native-access-control","title":"Native Access Control","text":"

    In this tutorial we\u2019ll use the go-SDK library to manage your buckets and objects.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#prerequisites","title":"Prerequisites","text":"

    Before getting started, you should be familiar with:

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#access-control-features","title":"Access Control Features","text":"Principal Effect Actions Resources Duration Accounts/Groups Allow/Deny UpdateBucketInfo, DeleteBucket, etc Bucket Accounts/Groups Allow/Deny CreateObject,DeleteObject,CopyObject,GetObject,ExecuteObject, etc Object Accounts/Groups Allow/Deny UpdateGroupMember,DeleteGroup, etc Group"},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#setup","title":"Setup","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#create-a-go-project","title":"Create a Go Project","text":"

    Let\u2019s set up a Go project with the necessary dependencies.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#init","title":"Init","text":"
    $ mkdir ~/hellogreenfield\n$ cd ~/hellogreenfield\n$ go mod init hellogreenfield\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#add-sdk-dependencies","title":"Add SDK Dependencies","text":"
    $ go get github.com/bnb-chain/greenfield-go-sdk\n

    Edit go.mod to replace dependencies

    replace (\n    cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9\n    cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9\n    github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2\n    github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1\n    github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3\n    github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1\n    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7\n)\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#install-dependensies","title":"Install dependensies","text":"
    go mod tidy\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#test-a-simple-function","title":"Test a simple function","text":"

    You can refer to the overview to learn about how to create a simple main.go

    If everything is set up correctly, your code will be able to connect to the Greenfield node and return the chain data as shown above.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#account-setup","title":"Account Setup","text":"

    You have to prepare two accounts, one is the principal, which acts like an admimistrator and a member, which will receive the access to view/update objects.

        account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n    if err != nil {\n        log.Fatalf(\"New account from private key error, %v\", err)\n    }\n    cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n    }\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#create-group","title":"Create Group","text":"

    The next step is to create a group, whose member will receive access from the principla account.

      // create group\n  groupTx, err := cli.CreateGroup(ctx, groupName, types.CreateGroupOptions{})\n  handleErr(err, \"CreateGroup\")\n  _, err = cli.WaitForTx(ctx, groupTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n\n  log.Printf(\"create group %s successfully \\n\", groupName)\n\n  // head group info\n  creator, err := cli.GetDefaultAccount()\n  handleErr(err, \"GetDefaultAccount\")\n  groupInfo, err := cli.HeadGroup(ctx, groupName, creator.GetAddress().String())\n  handleErr(err, \"HeadGroup\")\n  log.Println(\"head group info:\", groupInfo.String())\n\n  _, err = sdk.AccAddressFromHexUnsafe(memberAddress)\n  if err != nil {\n    log.Fatalln(\"the group member is invalid\")\n  }\n  // add group member\n  updateTx, err := cli.UpdateGroupMember(ctx, groupName, creator.GetAddress().String(), []string{memberAddress}, []string{},\n    types.UpdateGroupMemberOption{})\n  handleErr(err, \"UpdateGroupMember\")\n  _, err = cli.WaitForTx(ctx, updateTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n\n  log.Printf(\"add group member: %s to group: %s successfully \\n\", memberAddress, groupName)\n\n  // head group member\n  memIsExist := cli.HeadGroupMember(ctx, groupName, creator.GetAddress().String(), memberAddress)\n  if !memIsExist {\n    log.Fatalf(\"head group member %s fail \\n\", memberAddress)\n  }\n\n  log.Printf(\" head member %s exist \\n\", memberAddress)\n

    The result should look something similar to the following:

    2023/10/31 09:34:54 create group sample-group successfully\n2023/10/31 09:34:54 head group info: owner:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" group_name:\"sample-group\" id:\"720\"\n2023/10/31 09:35:01 add group member: 0x843e77D639b6C382e91ef489881963209cB238E5 to group: sample-group successfully\n2023/10/31 09:35:01  head member 0x843e77D639b6C382e91ef489881963209cB238E5 exist\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#create-policy","title":"Create Policy","text":"

    Now, you can let the principal grants the delete bucket, update bucket, delete object, update object access to this group

    // put bucket policy\n    bucketActions := []permTypes.ActionType{\n        permTypes.ACTION_UPDATE_BUCKET_INFO,\n        permTypes.ACTION_DELETE_BUCKET,\n        permTypes.ACTION_DELETE_OBJECT,\n        permTypes.ACTION_GET_OBJECT,\n    }\n    ctx := context.Background()\n    statements := utils.NewStatement(bucketActions, permTypes.EFFECT_ALLOW, nil, types.NewStatementOptions{})\n\n    policyTx, err := cli.PutBucketPolicy(ctx, bucketName, principalStr, []*permTypes.Statement{&statements},\n        types.PutPolicyOption{})\n    handleErr(err, \"PutBucketPolicy\")\n    _, err = cli.WaitForTx(ctx, policyTx)\n    if err != nil {\n        log.Fatalln(\"txn fail\")\n    }\n    log.Printf(\"put bucket %s policy sucessfully, principal is: %s.\\n\", bucketName, principal)\n

    After you run the code, the result should look something similar to the following:

    2023/10/31 10:46:55 put bucket sdkexamplebucket policy sucessfully, principal is:\n2023/10/31 10:46:55 bucket: sdkexamplebucket policy info:id:\"2358\" principal:<type:PRINCIPAL_TYPE_GNFD_ACCOUNT value:\"0x843e77D639b6C382e91ef489881963209cB238E5\" > resource_type:RESOURCE_TYPE_BUCKET resource_id:\"429\" statements:<effect:EFFECT_ALLOW actions:ACTION_UPDATE_BUCKET_INFO actions:ACTION_DELETE_BUCKET actions:ACTION_DELETE_OBJECT actions:ACTION_GET_OBJECT >\n
    You can also inspect using the block scanner, e.g. https://greenfieldscan.com."},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#verify-policy","title":"Verify Policy","text":"

    Here is an example to verify the policy metadata onchain:

    // get bucket policy\n  policyInfo, err := cli.GetBucketPolicy(ctx, bucketName, memberAddress)\n  handleErr(err, \"GetBucketPolicy\")\n  log.Printf(\"bucket: %s policy info:%s\\n\", bucketName, policyInfo.String())\n\n  // verify permission\n  effect, err := cli.IsBucketPermissionAllowed(ctx, memberAddress, bucketName, permTypes.ACTION_DELETE_BUCKET)\n  handleErr(err, \"IsBucketPermissionAllowed\")\n\n  if effect != permTypes.EFFECT_ALLOW {\n    log.Fatalln(\"permission not allowed to:\", principalStr)\n  }\n

    If the policy is recorded as expected, you will not see any error.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#delete-policy","title":"Delete Policy","text":"

    Here is an example to delete your bucket policy.

    The principalStr can be generated by NewPrincipalWithAccount or NewPrincipalWithGroupId method.

        // delete bucket policy\n    policyTx, err = cli.DeleteBucketPolicy(ctx, bucketName, principalStr, types.DeletePolicyOption{})\n    handleErr(err, \"DeleteBucketPolicy\")\n    _, err = cli.WaitForTx(ctx, policyTx)\n    if err != nil {\n        log.Fatalln(\"txn fail\")\n    }\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/","title":"Access Control Management with CLI - BNB Greenfield Access Control","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#access-control-management-with-cli","title":"Access Control Management with CLI","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#background","title":"Background","text":"

    In our last tutorial, we have guided you through the process of setting up your environment, installing the necessary tools, and effectively backing up your files to BNB Greenfield, leveraging the benefits of decentralized storage while ensuring data security and ownership.

    To dive furthur into advanced concepts of Greenfield, we will cover how to handle objects access control with the CLI tool, manage your groups and polocoes.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#verifying-the-environment","title":"Verifying the Environment","text":"

    Please refer to this doc to make sure you have completed installation of gnfd-cmd and setting up your accounts.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#query-bucket-info","title":"Query Bucket Info","text":"

    To query the bucket, execute:

    ./gnfd-cmd bucket head gnfd://website-bucket\n

    You should be able to see

    latest bucket info:\nowner:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"\nbucket_name:\"website-bucket\"\nvisibility:VISIBILITY_TYPE_PRIVATE\nid:\"3101\"\ncreate_at:2023-10-31 01:17:15\npayment_address:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"\nglobal_virtual_group_family_id:40\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#access-control-management-workflow-with-group","title":"Access Control Management Workflow with Group","text":"

    To manage how users can access your files, you have to follow this process: 1. Set Principle Address which has the administrator role 2. Customize groups members 3. Customize access policy, which may depends on different circustances 4. Bind/unbind policy with group

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#group-operations","title":"Group Operations","text":"

    The group commands is used to create group, update group members, delete group and query group info.

    To create a group one need to call the following storage create group command with the desired group name.

    // create group\ngnfd-cmd group create gnfd://website-group\n

    The operation will submit a transaction to BNB Greenfield blockchain to write the associated metadata. The result should look something similar to the following:

    make_group: gnfd://website-group\ntransaction hash: A1FD3A0E2A337716C344392B840DCC8E804553AF42504FBD6F4C46B9C5B8FAF9\ngroup id: 712\n

    As you can see, the result returns a transaction hash, which one can inspect using the block scanner, e.g. https://greenfieldscan.com. Going to https://testnet.greenfieldscan.com/tx/A1FD3A0E2A337716C344392B840DCC8E804553AF42504FBD6F4C46B9C5B8FAF9, will show all the details of the transaction.

    Add a new member to the group

    // update group member\ngnfd-cmd group update --addMembers 0x843e77D639b6C382e91ef489881963209cB238E5 gnfd://website-group\n

    To verify the new member is indeed part of the group

    // head group member\ngnfd-cmd group head-member  0x843e77D639b6C382e91ef489881963209cB238E5 website-group\n

    The result should look something similar to the following:

    the user 0x843e77D639b6C382e91ef489881963209cB238E5 is a member of the group: gnfd://website-group\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#policy-operations","title":"Policy Operations","text":"

    The gnfd-cmd policy command supports the policy for put/delete resources policy(including objects, buckets, and groups) to the principal.

    The principal is need to be set by --grantee which indicates a greenfield account or --groupId which indicates group id.

    The object policy action can be \u201ccreate\u201d, \u201cdelete\u201d, \u201ccopy\u201d, \u201cget\u201d , \u201cexecute\u201d, \u201clist\u201d or \u201call\u201d. The bucket policy actions can be \u201cupdate\u201d, \u201cdelete\u201d, \u201ccreate\u201d, \u201clist\u201d, \u201cupdate\u201d, \u201cgetObj\u201d, \u201ccreateObj\u201d and so on. The group policy actions can be \u201cupdate\u201d, \u201cdelete\u201d or all, update indicates the update-group-member action.

    In this example, the principal grants the delete bucket, update bucket access to this group

    // grant bucket operation permissions to a group\ngnfd-cmd policy put --groupId 712 --actions delete,update,createObj,getObj grn:b::website-bucket\n

    The result should look something similar to the following:

    put policy of the bucket:website-bucket succ, txn hash: 63735FBF6BDFF95AEED9B8BC8D794474431C77E7EBF768BFAA9E3F7CFB25FF97\nlatest bucket policy info:\n id:\"2316\" principal:<type:PRINCIPAL_TYPE_GNFD_GROUP value:\"172\" > resource_type:RESOURCE_TYPE_BUCKET resource_id:\"3101\" statements:<effect:EFFECT_ALLOW actions:ACTION_DELETE_BUCKET actions:ACTION_UPDATE_BUCKET_INFO actions:ACTION_CREATE_OBJECT >\n
    As you can see, the result returns a transaction hash, which one can inspect using the block scanner, e.g. https://greenfieldscan.com. Going to https://testnet.greenfieldscan.com/tx/63735FBF6BDFF95AEED9B8BC8D794474431C77E7EBF768BFAA9E3F7CFB25FF97, will show all the details of the put policy transaction.

    Upload a private file with principal account:

    gnfd-cmd object put --contentType \"text/xml\" --visibility private ./website/index.html gnfd://website-bucket/index.html\n

    In this example, the principal grants the delete object, update object access to this group

    // grant object operation permissions to a group\ngnfd-cmd policy put --groupId 712 --actions get,delete grn:o::website-bucket/index.html\n

    The result should look something similar to the following:

    put policy of the object:index.html succ, txn hash: BD2E3F74B2FBD18300B2C313E8F0393426C851EC3A9153F37DFD6CDC10F92FF8\nlatest object policy info:\n id:\"2318\" principal:<type:PRINCIPAL_TYPE_GNFD_GROUP value:\"712\" > resource_type:RESOURCE_TYPE_OBJECT resource_id:\"187293\" statements:<effect:EFFECT_ALLOW actions:ACTION_GET_OBJECT actions:ACTION_DELETE_OBJECT >\n

    To verify the group policy is working, you can try view the private object with account 0x843e77D639b6C382e91ef489881963209cB238E5. 1. Go to explorer and find the detail page of the private object. 2. Click on \u201cPreview\u201d button 3. Unlock your wallet and choose the right address. Then, you should be able to view the html file.

    or you can download the file with gnfd-cmd

    ./gnfd-cmd object get  gnfd://website-bucket/index.html\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#update-access-control-with-group","title":"Update Access Control with Group","text":"

    The command to update a group is very simple.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#remove-a-member-from-group","title":"Remove a member from group:","text":"
    // update group member\ngnfd-cmd group update --removeMembers 0xca807A58caF20B6a4E3eDa3531788179E5bc816b gnfd://groupname\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#add-expiretime-for-membership","title":"Add expiretime for membership","text":"

    You can set the expire timestamp for the newly added member. The default value is no experiation.

    // update group member\ngnfd-cmd group update --removeMembers 0xca807A58caF20B6a4E3eDa3531788179E5bc816b gnfd://groupname --expireTime 1699699763\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#remove-policy","title":"Remove Policy","text":"

    Here is an example to delete a policy * Delete a policy for an adress

    gnfd-cmd policy rm --grantee 0x843e77D639b6C382e91ef489881963209cB238E5 --actions get grn:o::website-bucket/index.html\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#conclusion","title":"Conclusion","text":"

    Overall, the access control management of Greenfield is very powerful and can be used in many scenarios. It is highly recommended for users to engage in hands-on exploration by trying out different account group management operations and permissioning mechanisms. This will provide a deeper understanding of how BNB Greenfield functions and how to effectively manage and secure data within the decentralized storage system.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/","title":"Cross Chain Access Control by CMD - BNB Greenfield Access Control","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/#cross-chain-access-control-by-cmd","title":"Cross Chain Access Control by CMD","text":"

    In this guide, we will walk you through the process of data permission management using the BSC smart contract as a simple howcase of cross chain program-ability of Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/#prerequisites","title":"Prerequisites","text":"

    Before starting, make sure you have the following tools installed:

    Please follow the readme of the above two repositories to install the tools and configure the environment.

    Ensure you get an account that get funds on both BSC and Greenfield network.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/#steps","title":"Steps","text":"

    In the following example, Account A(0x0fEd1aDD48b497d619EF50160f9135c6E221D5F0, stored in keyA.json) will grant Account B(0x3bD70E10D71C6E882E3C1809d26a310d793646eB, stored in keyB.json) the access to his private file through BSC contract.

    Besides, you can save the password to a file and use -p to specify the password file. For example, gnfd-cmd -p password.txt ....

    Before starting, please make sure you created related accounts by gnfd-cmd account import or gnfd-cmd account new and have the config.toml file in the current directory. Please note that the account should have enough balance before sending transactions to greenfield.

    The content of the config.toml is as follows:

    MainnetTestnet
    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\nchainId = \"greenfield_1017-1\"\n
    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\nchainId = \"greenfield_5600-1\"\n
    1. Prepare environment

      $ export AccountA=0x0fEd1aDD48b497d619EF50160f9135c6E221D5F0\n$ export AccountB=0x3bD70E10D71C6E882E3C1809d26a310d793646eB\n
    2. Create a temporary file story.txt

      $ echo \"this is a fun story\" > story.txt \n
    3. Create a bucket named funbucket.

      $ gnfd-cmd -c config.toml -k keyA.json -p password.txt bucket create gnfd://funbucket\n
    4. Create a private object named story.txt in the bucket funbucket.

      $ gnfd-cmd -c config.toml -k keyA.json -p password.txt object put --contentType \"text/xml\" --visibility private ./story.txt  gnfd://funbucket/story.txt\n
    5. Create a group named fungroup.

      $ gnfd-cmd -c config.toml -k keyA.json -p password.txt group create fungroup\ncreate group: fungroup succ, txn hash:17B6AE2C8D30B6D6EEABEE81DB8B37CF735655E9087CB02DC98EFF1DCA9FBE3A, group id: 136 \n

      The console will return the id of the group, which is 136 in this case.

    6. Bind the group fungroup to the object story.txt.

      ## Example, replace the ${GroupId} with the group id you get in the previous step\n$ export GroupId=136\n$ gnfd-cmd -c config.toml -k keyA.json -p password.txt policy put --groupId ${GroupId} --actions get grn:o::funbucket/story.txt   \n
    7. Mirror the group to BSC network.

      ## Example, replace the ${GroupId} with the group id you get in the previous step\n## 97 is the chainId of BSC testnet\n## 56 is the chainId of BSC mainnet\n\n$ export ChainId=56\n$ gnfd-cmd -c config.toml -k keyA.json -p password.txt group mirror --destChainId ${GroupId} --id ${GroupId} \n
    8. Try to access the file through AccountB.

      ## Example\n$ gnfd-cmd -c config.toml -k keyA.json -p password.txt group head-member --groupOwner ${AccountA}  ${AccountB}  fungroup\nthe user does not exist in the group\n$ gnfd-cmd -c config.toml -k keyB.json -p password.txt object get gnfd://funbucket/story.txt ./story-copy.txt\nrun command error: statusCode 403 : code : AccessDenied  (Message: Access Denied)\n

      It turns out that AccountB is not permitted to access the file, which is expected.

    9. Clone the gnfd-contract repository and install the dependencies.

    10. Grant the access to Account B through the contract.

      MainnetTestnet
      export RPC_MAIN=https://bsc-dataseed.bnbchain.org\n$ forge script foundry-scripts/GroupHub.s.sol:GroupHubScript \\\n--sig \"addMember(address operator, uint256 groupId, address member)\" \\\n${AccountA} ${GroupId} ${AccountB} \\\n-f $RPC_MAIN \\\n--private-key 148748590a8b83dxxxxxxxxxxxxxxxxx \\\n--legacy \\\n--broadcast     \n
      export RPC_TEST=https://bsc-testnet-dataseed.bnbchain.org\n$ forge script foundry-scripts/GroupHub.s.sol:GroupHubScript \\\n--sig \"addMember(address operator, uint256 groupId, address member)\" \\\n${AccountA} ${GroupId} ${AccountB} \\\n-f $RPC_TEST\\\n--private-key 148748590a8b83dxxxxxxxxxxxxxxxxx \\\n--legacy \\\n--broadcast\n
    11. Wait 30 seconds, and try to access the file through AccountB again.

      ## Example\n$ gnfd-cmd -c config.toml -k keyA.json -p password.txt group head-member --groupOwner ${AccountA}  ${AccountB} fungroup\nthe user is a member of the group\n$ gnfd-cmd -c config.toml -k keyB.json -p password.txt object get gnfd://funbucket/story.txt \ndownload object story.txt successfully, the file path is ./story-copy.txt, content length:20\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/","title":"Cross Chain Access Control by SDK - BNB Greenfield Access Control","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#cross-chain-access-control-by-sdk","title":"Cross Chain Access Control by SDK","text":"

    In this tutorial we\u2019ll use the go-SDK library to transfer control over objects to the smart contract on BSC and allowing on-chain management. Object mirroring enables greater flexibility and control over decentralized storage on BNB Greenfield to all dApps on BSC. It leverages the capabilities of the BSC and its smart contract functionality to provide enhanced functionality and interoperability between the two platforms.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#prerequisites","title":"Prerequisites","text":"

    Before getting started, you should be familiar with:

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#cross-chain-mechanism","title":"Cross Chain Mechanism","text":"

    Cross-chain communication serves as the foundation for enabling the exchange of assets, data, and functionalities across disparate blockchains, facilitating a more connected and efficient decentralised ecosystem.

    Cross-communication between BNB Greenfield and BSC stands apart from the approaches taken by Polkadot, Chainlink, and Cosmos in several significant aspects.

    Cross chain communication features BNB Greenfield/BSC Cosmos/IBC Polkadot Chainlink CCIP Bulk messaging Custom and performant General application General application General application Compatibility Fully compatible with EVM and Ethereum L2s Only Cosmos ecosystem Only Polkadot ecosystem Specific implementations for each blockchain Security Model Own validators Shared Shared Own validators Tokenomics BNB ATOM DOT LINK Address Scheme Unified - same addresses Can be different addresses Can be different addresses Can be different addresses Composability Shared components with BNB Chain ecosystem Implementation in progress Shared components with Polkadot ecosystem New implementation for each network"},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#account-setup","title":"Account Setup","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#create-a-go-project","title":"Create a Go Project","text":"

    Let\u2019s set up a Go project with the necessary dependencies.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#init","title":"Init","text":"
    $ mkdir ~/hellogreenfield\n$ cd ~/hellogreenfield\n$ go mod init hellogreenfield\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#add-sdk-dependencies","title":"Add SDK Dependencies","text":"
    $ go get github.com/bnb-chain/greenfield-go-sdk\n

    Edit go.mod to replace dependencies

    replace (\n    cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9\n    cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9\n    github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2\n    github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1\n    github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3\n    github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1\n    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7\n)\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#install-dependensies","title":"Install dependensies","text":"
    go mod tidy\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#test-a-simple-function","title":"Test a simple function","text":"

    You can refer to the overview to learn about how to create a simple main.go

    If everything is set up correctly, your code will be able to connect to the Greenfield node and return the chain data as shown above.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#account-setup_1","title":"Account setup","text":"
    account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n    if err != nil {\n        log.Fatalf(\"New account from private key error, %v\", err)\n    }\n    cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n    }\n    ctx := context.Background()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#create-buckets","title":"Create Buckets","text":"

    Now, let\u2019s use the imported account to create a bucket.

    In this example,

        // get storage providers list\n    spLists, err := cli.ListStorageProviders(ctx, true)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n    }\n    // choose the first sp to be the primary SP\n    primarySP := spLists[0].GetOperatorAddress()\n\n    bucketName := storageTestUtil.GenRandomBucketName()\n\n    txHash, err := cli.CreateBucket(ctx, bucketName, primarySP, types.CreateBucketOptions{})\n    handleErr(err, \"CreateBucket\")\n    log.Printf(\"create bucket %s on SP: %s successfully \\n\", bucketName, spLists[0].Endpoint)\n\n    waitForTx, _ := cli.WaitForTx(ctx, txHash)\n    log.Printf(\"Wait for tx: %s\", waitForTx.TxResult.String())\n

    The example return message is like the following:

    2023/10/31 13:14:54 create bucket ylatitsb on SP: https://gnfd-testnet-sp1.bnbchain.org successfully\n2023/10/31 13:14:54 Wait for tx: data:\"\\0225\\n+/greenfield.storage.MsgCreateBucketResponse\\022\\006\\n\\0043175\\032\\010\\000\\000\\000\\000\\000\\000\\201\\006\" log:\"[{\\\"msg_index\\\":0,\\\"events\\\":[{\\\"type\\\":\\\"message\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"action\\\",\\\"value\\\":\\\"/greenfield.storage.MsgCreateBucket\\\"},{\\\"key\\\":\\\"sender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"module\\\",\\\"value\\\":\\\"storage\\\"}]},{\\\"type\\\":\\\"greenfield.storage.EventCreateBucket\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"bucket_id\\\",\\\"value\\\":\\\"\\\\\\\"3175\\\\\\\"\\\"},{\\\"key\\\":\\\"bucket_name\\\",\\\"value\\\":\\\"\\\\\\\"ylatitsb\\\\\\\"\\\"},{\\\"key\\\":\\\"charged_read_quota\\\",\\\"value\\\":\\\"\\\\\\\"0\\\\\\\"\\\"},{\\\"key\\\":\\\"create_at\\\",\\\"value\\\":\\\"\\\\\\\"1698779691\\\\\\\"\\\"},{\\\"key\\\":\\\"global_virtual_group_family_id\\\",\\\"value\\\":\\\"40\\\"},{\\\"key\\\":\\\"owner\\\",\\\"value\\\":\\\"\\\\\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\\\\\"\\\"},{\\\"key\\\":\\\"payment_address\\\",\\\"value\\\":\\\"\\\\\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\\\\\"\\\"},{\\\"key\\\":\\\"primary_sp_id\\\",\\\"value\\\":\\\"1\\\"},{\\\"key\\\":\\\"source_type\\\",\\\"value\\\":\\\"\\\\\\\"SOURCE_TYPE_ORIGIN\\\\\\\"\\\"},{\\\"key\\\":\\\"status\\\",\\\"value\\\":\\\"\\\\\\\"BUCKET_STATUS_CREATED\\\\\\\"\\\"},{\\\"key\\\":\\\"visibility\\\",\\\"value\\\":\\\"\\\\\\\"VISIBILITY_TYPE_PRIVATE\\\\\\\"\\\"}]}]}]\" gas_wanted:2400 gas_used:2400 events:<type:\"coin_spent\" attributes:<key:\"spender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"12000000000000BNB\" index:true > > events:<type:\"coin_received\" attributes:<key:\"receiver\" value:\"0xf1829676DB577682E944fc3493d451B67Ff3E29F\" index:true > attributes:<key:\"amount\" value:\"12000000000000BNB\" index:true > > events:<type:\"transfer\" attributes:<key:\"recipient\" value:\"0xf1829676DB577682E944fc3493d451B67Ff3E29F\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"12000000000000BNB\" index:true > > events:<type:\"message\" attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > > events:<type:\"tx\" attributes:<key:\"fee\" value:\"12000000000000BNB\" index:true > attributes:<key:\"fee_payer\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > > events:<type:\"tx\" attributes:<key:\"acc_seq\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd/70\" index:true > > events:<type:\"tx\" attributes:<key:\"signature\" value:\"aKL7wpB1b0107d1OleaHKKBw5mXUskggINbq7hsr90s6MzgV88DxjAGak37xz9V4LsoH0sr7saqBmBrE5MKJtgA=\" index:true > > events:<type:\"message\" attributes:<key:\"action\" value:\"/greenfield.storage.MsgCreateBucket\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"module\" value:\"storage\" index:true > > events:<type:\"greenfield.storage.EventCreateBucket\" attributes:<key:\"bucket_id\" value:\"\\\"3175\\\"\" index:true > attributes:<key:\"bucket_name\" value:\"\\\"ylatitsb\\\"\" index:true > attributes:<key:\"charged_read_quota\" value:\"\\\"0\\\"\" index:true > attributes:<key:\"create_at\" value:\"\\\"1698779691\\\"\" index:true > attributes:<key:\"global_virtual_group_family_id\" value:\"40\" index:true > attributes:<key:\"owner\" value:\"\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"\" index:true > attributes:<key:\"payment_address\" value:\"\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"\" index:true > attributes:<key:\"primary_sp_id\" value:\"1\" index:true > attributes:<key:\"source_type\" value:\"\\\"SOURCE_TYPE_ORIGIN\\\"\" index:true > attributes:<key:\"status\" value:\"\\\"BUCKET_STATUS_CREATED\\\"\" index:true > attributes:<key:\"visibility\" value:\"\\\"VISIBILITY_TYPE_PRIVATE\\\"\" index:true > >\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#create-group","title":"Create Group","text":"

    The next step is to create a group, whose member will receive get object access from the principla account.

      // create group\n  groupTx, err := cli.CreateGroup(ctx, groupName, types.CreateGroupOptions{})\n  handleErr(err, \"CreateGroup\")\n  _, err = cli.WaitForTx(ctx, groupTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n\n  log.Printf(\"create group %s successfully \\n\", groupName)\n\n  // head group info\n  creator, err := cli.GetDefaultAccount()\n  handleErr(err, \"GetDefaultAccount\")\n  groupInfo, err := cli.HeadGroup(ctx, groupName, creator.GetAddress().String())\n  handleErr(err, \"HeadGroup\")\n  log.Println(\"head group info:\", groupInfo.String())\n\n  _, err = sdk.AccAddressFromHexUnsafe(memberAddress)\n  if err != nil {\n    log.Fatalln(\"the group member is invalid\")\n  }\n  // add group member\n  updateTx, err := cli.UpdateGroupMember(ctx, groupName, creator.GetAddress().String(), []string{memberAddress}, []string{},\n    types.UpdateGroupMemberOption{})\n  handleErr(err, \"UpdateGroupMember\")\n  _, err = cli.WaitForTx(ctx, updateTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n\n  log.Printf(\"add group member: %s to group: %s successfully \\n\", memberAddress, groupName)\n\n  // head group member\n  memIsExist := cli.HeadGroupMember(ctx, groupName, creator.GetAddress().String(), memberAddress)\n  if !memIsExist {\n    log.Fatalf(\"head group member %s fail \\n\", memberAddress)\n  }\n\n  log.Printf(\" head member %s exist \\n\", memberAddress)\n

    The result should look something similar to the following:

    2023/10/31 09:34:54 create group sample-group successfully\n2023/10/31 09:34:54 head group info: owner:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" group_name:\"sample-group\" id:\"720\"\n2023/10/31 09:35:01 add group member: 0x843e77D639b6C382e91ef489881963209cB238E5 to group: sample-group successfully\n2023/10/31 09:35:01  head member 0x843e77D639b6C382e91ef489881963209cB238E5 exist\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#create-policy","title":"Create Policy","text":"

    Now, you can let the principal grants the get object access to this group

    // put bucket policy\n    bucketActions := []permTypes.ActionType{\n        permTypes.ACTION_GET_OBJECT,\n    }\n    ctx := context.Background()\n    statements := utils.NewStatement(bucketActions, permTypes.EFFECT_ALLOW, nil, types.NewStatementOptions{})\n\n    policyTx, err := cli.PutBucketPolicy(ctx, bucketName, principalStr, []*permTypes.Statement{&statements},\n        types.PutPolicyOption{})\n    handleErr(err, \"PutBucketPolicy\")\n    _, err = cli.WaitForTx(ctx, policyTx)\n    if err != nil {\n        log.Fatalln(\"txn fail\")\n    }\n    log.Printf(\"put bucket %s policy sucessfully, principal is: %s.\\n\", bucketName, principal)\n

    After you run the code, the result should look something similar to the following:

    2023/10/31 10:46:55 put bucket sdkexamplebucket policy sucessfully, principal is:\n2023/10/31 10:46:55 bucket: sdkexamplebucket policy info:id:\"2358\" principal:<type:PRINCIPAL_TYPE_GNFD_ACCOUNT value:\"0x843e77D639b6C382e91ef489881963209cB238E5\" > resource_type:RESOURCE_TYPE_BUCKET resource_id:\"429\" statements:<effect:EFFECT_ALLOW actions:ACTION_UPDATE_BUCKET_INFO actions:ACTION_DELETE_BUCKET actions:ACTION_DELETE_OBJECT actions:ACTION_GET_OBJECT >\n
    You can also inspect using the block scanner, e.g. https://greenfieldscan.com."},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#mirror-group-to-bsc","title":"Mirror Group to BSC","text":"

    In Greenfield, object mirroring refers to the process of transferring control over objects stored on BNB Greenfield to a smart contract on BNB Smart Chain (BSC)

    This allows the object to be fully managed on-chain on BSC, meaning that users or other smart contracts can perform various operations and changes to the object through on-chain transactions.

    During the mirroring process from BNB Greenfield to BSC, the content of the file itself is not copied. This means that neither the data nor the file metadata, which is stored on the BNB Greenfield blockchain, is transferred to BSC.

        //head group\n    groupInfo, err := cli.HeadGroup(ctx, groupName, creator.GetAddress().String())\n    handleErr(err, \"HeadGroup\")\n    log.Println(\"head group info:\", groupInfo.String())\n\n    // mirror bucket\n    txResp, err := cli.MirrorGroup(ctx, sdk.ChainID(crossChainDestBsChainId), groupInfo.Id, groupName, gnfdSdkTypes.TxOption{})\n    handleErr(err, \"MirrorGroup\")\n    waitForTx, _ = cli.WaitForTx(ctx, txResp.TxHash)\n    log.Printf(\"Wait for tx: %s\", waitForTx.TxResult.String())\n    log.Printf(\"successfully mirrored group wiht  id %s to BSC\", groupInfo.Id)\n
    2023/10/31 21:43:57 group: sdkexamplegroup policy info:id:\"712\" principal:<type:PRINCIPAL_TYPE_GNFD_ACCOUNT value:\"0x843e77D639b6C382e91ef489881963209cB238E5\" > resource_type:RESOURCE_TYPE_BUCKET resource_id:\"429\" statements:<effect:EFFECT_ALLOW actions:ACTION_GET_OBJECT >\n2023/10/31 21:43:57 bucket info: owner:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" bucket_name:\"ylatitsb\" visibility:VISIBILITY_TYPE_PRIVATE id:\"3175\" create_at:1698779691 payment_address:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" global_virtual_group_family_id:40\n

    You can also inspect using the block scanner, e.g. https://greenfieldscan.com.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#access-control-management-on-bsc","title":"Access Control Management on BSC","text":"

    Now you have mirrored your group to BSC and there is an ERCC-721 token minted. At present, the NFTs are not transferable. The group membership can be directly managed by smart contracts on BSC. These operations will directly affect the storage format, access permissions, and other aspects of the data on greenfield with the help of Greenfield Contract.

    First, you have to install the dependencies and setup environment by following the guides.

    Once it\u2019s all set, you can run the following script to add member to your group:

    # set your private-key, operator address, group id, and member address\nforge script foundry-scripts/GroupHub.s.sol:GroupHubScript \\\n--private-key ${your private key} \\\n--sig \"addMember(address operator, uint256 groupId, address member)\" \\\n${the owner of the group} ${your group id} ${the member address to add} \\\n-f https://data-seed-prebsc-1-s1.binance.org:8545/ \\\n--legacy --ffi --broadcast\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#conclusion","title":"Conclusion","text":"

    The Greenfield Blockchain provides a comprehensive set of resources that can be mirrored on the BNB Smart Chain (BSC). This includes buckets, objects, and groups, which can be stored and managed on the BSC as non-fungible tokens (NFTs) conforming to the ERC-721 standard. This integration between Greenfield Blockchain and BNB Smart Chain allows for greater flexibility and accessibility when it comes to accessing and manipulating data, ultimately leading to a more streamlined and efficient data management process.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/data-marketplace/","title":"MindPress Data Marketplace Introduction - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/data-marketplace/#mindpress-data-marketplace-introduction","title":"MindPress Data Marketplace Introduction","text":"1. Overview

    MindPress Data Marketplace is a demo built on the BNB Smart Chain and BNB Greenfield storage chains. It uses the image trading scenario as an example to demonstrate the use of BNB Greenfield\u2019s latest release (V1.6&V1.7), such as cross-chain programmability, delegate upload, and sponsor-paid storage fees. With these features, developers can easily create a web3 decentralized trading platform based on the BNB Chain ecosystem with a great user experience and comprehensive functions such as storage, trading, and content permission management, thereby accelerating project development and marketing.

    2. Features

    As an image stock, sellers can upload and list photos for sale, while buyers can search for images they like, buy, and download the original files.

    Seller

    Buyer

    3. Benefits after Greenfield V1.6&1.7 updates # Before After Code Related Greenfield Features Network Switch \u274cUsers have to switch between BNB Greenfield and BNB Smart Chain to upload objects and make the trading operation. \u2705No network switch: Users can finish all the operations on BSC network. https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/417 Payment Method \u274cUsers have to pay the storage fee and download quota fee by themselves. \u2705Flexible payment method: Projects can choose to pay storage and download quota fees by themselves, allowing users to use this platform for free and lowering the user threshold, thereby expanding the number of users and facilitating promotion. https://github.com/bnb-chain/greenfield/pull/582 Upload Objects \u274cUsers must upload objects to DCellar before returning to MindPress to list them because the upload process is quite complex to embed in MindPress. \u2705Easy to upload: Users can upload multiple large objects in MindPress at once without requiring a signature or incurring fees because the upload process is greatly simplified by the delegate upload feature. https://github.com/bnb-chain/greenfield/pull/581 List Objects \u274cUsers have to execute 2-3 transactions to complete the list workflow, which also requires switching networks back and forth. \u2705Easy to list: Users need only 2 transactions to complete the list operation to start selling. https://github.com/bnb-chain/greenfield-contracts/pull/140 4. Demo Video 4.1 Buyer workflow Search and filter Buy Images 4.2 Seller Workflow Upload Images List Images Delist Images 5. Environment Support 6. Technical Design 6.1 Overview

    The BNB Greenfield offers resources such as buckets, objects, and groups that can be mirrored on the BNB Smart Chain (BSC) as non-fungible tokens (NFTs) following the ERC-721 standard. Buckets store objects, the basic units with data and metadata. Groups consist of accounts with similar permissions. These resources, including group members\u2019 permissions as ERC-1155 tokens, can be mirrored on the BSC.

    Smart contracts on BSC can directly control mirrored resources, affecting storage formats, access permissions, and other data aspects on Greenfield. This integration boosts flexibility and accessibility, streamlining data management on both platforms. For more on mirroring implementation, refer to this document.

    In the context of the MindPress Data Marketplace, users have the ability to store images on the Greenfield network and sell them on the BSC. Let\u2019s take the example of Alice selling a picture of a carrot on MindPress. To sell carrot images, Alice needs to follow these steps:

    1. Create a bucket, and upload the carrot image to this bucket on BNB Greenfield.
    2. Create a group and grant this group permission to view the carrot image.
    3. List the group on the MindPress Data Marketplace smart contract to sell access permissions on the BSC network.

    Since the carrot image is private, Bob will be denied access to it by default.

    Bob needs to buy permission to join the group. After becoming a member, he can view/download the carrot image.

    6.2 Architecture 6.2.1 Greenfield Cross Chain Design

    The true strength of the Greenfield ecosystem resides in its cutting-edge platform engineered not just for data storage, but also for fostering value creation from data assets and its associated economy. To empower data on Greenfield more effectively, a robust cross-chain mechanism has been introduced, enabling versatile cross-chain programming capabilities.

    The first layer is the Cross-Chain Communication Layer, which is responsible for handling and verifying the communication packages between BSC and BNB Greenfield.

    The second layer is the Resource Mirror Layer, which handles the resource assets defined on BNB Greenfield and mirrors them onto BSC.

    The top layer of the cross-chain system is the Application Layer. This layer consists of smart contracts that are developed by the community on BSC, enabling them to operate the mirrored resource entities on the Resource Mirror Layer.

    6.2.2 MindPress Workflow

    MindPress Data Marketplace is built on the cross-chain mechanism of BNB Greenfield and BSC, enabling users to flexibly manipulate data stored on Greenfield on the BSC side, facilitating data circulation and value creation. Below, we delve into the technical principles of the key processes involved in MindPress.

    The MindPress contract will do the following operations:

    1. help the user to create a bucket to store the uploaded images and the paymaster of the bucket is set to mindpress contract.
    2. set the flow rate limit for the bucket to give the initial free charge.

    Users should go through the following 2 transactions to list an object:

    1. Send a list request to the MindPress contract with the object ID, group name and price, MindPress will create a new group where all members of the group have access to the object.
    2. Send a cross-chain put-policy transaction to bind the object and the created group.

    6.3 Technical Considerations 7. Getting Started

    MindPress consists of three engineering projects:

    8. Contributing

    Thank you for considering using and contributing to MindPress! We welcome developers to utilize our open-source codebase and encourage collaboration to improve and extend its functionality. If you have any questions, feel free to reach out to us for assistance. Happy coding!

    9. License

    The library is licensed under the GNU Lesser General Public License v3.0, also included in our repository in the LICENSE file.

    10. Disclaimer

    The software and related documentation are under active development, all subject to potential future change without notification and not ready for production use. The code and security audit have not been fully completed and are not ready for any bug bounty. We advise you to be careful and experiment on the network at your own risk. Stay safe out there.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/","title":"Overview - BNB Greenfield App","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#overview","title":"Overview","text":"

    Native apps are applications developed only using the Greenfield SDK, without involving the development of smart contracts.

    In the following sections, we will delve deeper into each native application, providing step-by-step guides, code snippets, and best practices to empower you to create powerful and innovative dApps without the need for smart contract development.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#data-marketplace","title":"Data Marketplace","text":"

    Data marketplace is a data exchange platform where users can freely create, list, trade, and sell data assets, including digital publications, scientific experimental data, and specific domain data.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#demo-link","title":"Demo Link","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#source-code","title":"Source Code","text":"

    MindPress consists of three engineering projects:

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#developing-with-smart-contracts-on-bsc","title":"Developing with smart contracts on BSC","text":"

    One of the primary methods for building dApps with BNB Greenfield is by deploying smart contracts to the BSC. Smart contracts are self-executing programs that facilitate and enforce the execution of agreements without the need for intermediaries.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#cli","title":"CLI","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#sdk-demo","title":"SDK Demo","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/","title":"Simple Tool for File Management - BNB Greenfield File Management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#building-file-management-tool-with-greenfield-sdk","title":"Building File Management Tool with Greenfield SDK","text":"

    Several Chain API libraries are available. These libraries manage the low-level logic of connecting to Greenfield node, making requests, and handing the responses. * go-sdk * js-sdk

    In this tutorial we\u2019ll use the go-SDK library to interact with testnet.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#prerequisites","title":"Prerequisites","text":"

    Before getting started, you should be familiar with: * Greenfield basics * Greenfield command line examples

    Also, make sure you have the following dependencies installed with the latest version: * Go version above 1.20

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#go-sdk-features","title":"Go-SDK Features","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#setup","title":"Setup","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#create-a-go-project","title":"Create a Go Project","text":"

    Let\u2019s set up a Go project with the necessary dependencies.

    Init

    $ mkdir ~/hellogreenfield\n$ cd ~/hellogreenfield\n$ go mod init hellogreenfield\n

    Add SDK Dependencies

    $ go get github.com/bnb-chain/greenfield-go-sdk\n

    Edit go.mod to replace dependencies

    replace (\n    cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9\n    cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9\n    github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2\n    github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1\n    github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3\n    github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1\n    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7\n)\n

    Install dependensies

    go mod tidy\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#test-a-simple-function","title":"Test a simple function","text":"

    Now we\u2019re ready to connect to Greenfield testnet and interact with the storage provider APIs. Let\u2019s write a simple script to query the Greenfield version to verify if everything works as expected.

    Create a main.go file in your project and add the following code.

    package main\n\nimport (\n  \"context\"\n  \"log\"\n\n  \"github.com/bnb-chain/greenfield-go-sdk/client\"\n  \"github.com/bnb-chain/greenfield-go-sdk/types\"\n)\n\nconst (\n  rpcAddr    = \"https://greenfield-chain.bnbchain.org:443\"\n  chainId    = \"greenfield_1017-1\"\n  /*testnet\n  rpcAddr    = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n  chainId    = \"greenfield_5600-1\"\n  */\n  privateKey = \"\"\n)\n\nfunc main() {\n  account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n  if err != nil {\n    log.Fatalf(\"New account from private key error, %v\", err)\n  }\n\n  cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n  if err != nil {\n    log.Fatalf(\"unable to new greenfield client, %v\", err)\n  }\n\n  ctx := context.Background()\n  nodeInfo, versionInfo, err := cli.GetNodeInfo(ctx)\n  if err != nil {\n    log.Fatalf(\"unable to get node info, %v\", err)\n  }\n\n  log.Printf(\"nodeInfo moniker: %s, go version: %s\", nodeInfo.Moniker, versionInfo.GoVersion)\n  latestBlock, err := cli.GetLatestBlock(ctx)\n  if err != nil {\n    log.Fatalf(\"unable to get latest block, %v\", err)\n  }\n  log.Printf(\"latestBlock header: %s\", latestBlock.Header)\n\n  heightBefore := latestBlock.Header.Height\n  log.Printf(\"Wait for block height: %d\", heightBefore)\n  err = cli.WaitForBlockHeight(ctx, heightBefore+10)\n  if err != nil {\n    log.Fatalf(\"unable to wait for block height, %v\", err)\n  }\n  height, err := cli.GetLatestBlockHeight(ctx)\n  if err != nil {\n    log.Fatalf(\"unable to get latest block height, %v\", err)\n  }\n\n  log.Printf(\"Current block height: %d\", height)\n}\n

    Run the following command in your project directory:

    go run main.go\n
    This will output something like:
    2023/09/12 22:18:10 nodeInfo moniker: fullnode, go version: go version go1.20.7 linux/amd64\n2023/09/12 22:18:10 latestBlock header: {{%!s(uint64=11) %!s(uint64=0)} greenfield_5600-1 %!s(int64=401149) 2023-09-13 04:18:05.661693468 +0000 UTC\n{\n    \"header\": {\n      \"version\": {\n        \"block\": \"11\",\n        \"app\": \"0\"\n      },\n      \"chain_id\": \"greenfield_5600-1\",\n      \"height\": \"401149\",\n      \"time\": \"2023-09-13T04:18:05.661693468Z\",\n      \"last_block_id\": {\n        \"hash\": \"KenBGYDrtA7Bnyy6j3R3d16GWuHnIl5gJW0J3kmM4r8=\",\n        \"part_set_header\": {\n          \"total\": 1,\n          \"hash\": \"W6nmeVJEhHinvI4I6HBsU/A87Zma8DVVvddBATJdctE=\"\n        }\n      },\n      \"last_commit_hash\": \"/G92Jzr8fPpqKY89F3xa3dytOF8a2HLvqCrccm9scXM=\",\n      \"data_hash\": \"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\",\n      \"validators_hash\": \"FykCd/548F1J28ssZr71B1805hzxENaQvexsW/Dxo3E=\",\n      \"next_validators_hash\": \"FykCd/548F1J28ssZr71B1805hzxENaQvexsW/Dxo3E=\",\n      \"consensus_hash\": \"FgA8CM0pWCco2OYq8pA9tuklVX8bmHmMV2Ssdj31W4E=\",\n      \"app_hash\": \"wv+XqXhJBQPYpat/Obaj00u86KfJ8le4LIIFFAgqVmA=\",\n      \"last_results_hash\": \"f6XeDeH8QasoTSGpSJL0r2WGE4MlrXOVt0cE3bIQE8I=\",\n      \"evidence_hash\": \"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\",\n      \"proposer_address\": \"KhlQ9bz1O8iaWZnqKe36m3IpcP4=\",\n      \"randao_mix\": \"/6zQmCJztTeqZIRHe/pXxhgSbfwDLE85awoa4c8sShUUwGGLqFyshMag63MTB7JC2fAsUqPg1ryALY+uQNZ3Bw==\"\n    }\n}\n2023/09/12 22:18:10 Wait for block height: 401149\n2023/09/12 22:18:34 Current block height: 401159\n
    If everything is set up correctly, your code will be able to connect to the Greenfield node and return the chain data as shown above."},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#get-chain-data","title":"Get Chain Data","text":"

    In the previous step, we created a main.go file to demonstrate the basic steps to connect to the node and initialize a Client to query chain data. Next, let\u2019s use some more functions. Get current chain head: We can add the following code in main.go to query current head of the chain.

      blockByHeight, err := cli.GetBlockByHeight(ctx, height)\n  if err != nil {\n    log.Fatalf(\"unable to get block by height, %v\", err)\n  }\n  log.Printf(\"Current block height: %d\", blockByHeight.Header)\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#get-address-balance","title":"Get Address balance","text":"

    With a given greenfield wallet address, you can query its balance by calling GetAccountBalance function.

      balance, err := cli.GetAccountBalance(ctx, account.GetAddress().String())\n  if err != nil {\n    log.Fatalf(\"unable to get balance, %v\", err)\n  }\n  log.Printf(\"%s Current balance: %s\", account.GetAddress().String(), balance.String())\n

    Apart from the basic data queries shown above, there are many more features. Please see the JSON-RPC API Reference for all Greenfield API definitions.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#manage-wallet","title":"Manage Wallet","text":"

    Greenfield wallets hold addresses that you can use to manage objects, sign transactions, and pay for gas fees. In this section, we will demonstrate different ways to manage your wallet. 1. First, let\u2019s make sure your connected node is running and the wallet address contains some testnet BNB. 2. Create a new file called account.go in the same project as earlier. This is where we\u2019ll write all out wallet-related code. 3. In account.go import modules and initialize your private key or mnemonic phrase.

      //import mnemonic\n  account, err := types.NewAccountFromMnemonic(\"test\", mnemonic)\n  //import private key\n  account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n

    Let\u2019s create a second wallet address so we can test transfers. The new address will be created locally and start with 0 token balance:

      account2, _, err := types.NewAccount(\"test2\")\n

    Now, let\u2019s try to transfer tBNB to this new address. Under the hood, this will create a transaction to transfer tBNB from fromAddress to toAddress, sign the transaction using SDK, and send the signed transaction to the Greenfield node.

        transferTxHash, err := cli.Transfer(ctx, account2.GetAddress().String(), math.NewIntFromUint64(10000000000), types2.TxOption{})\n   if err != nil {\n    log.Fatalf(\"unable to send, %v\", err)\n   }\n   log.Printf(\"Transfer response: %s\", transferTxHash)\n\n   waitForTx, err := cli.WaitForTx(ctx, transferTxHash)\n\n   log.Printf(\"Wair for tx: %s\", waitForTx.TxResult.String())\n\n   balance, err = cli.GetAccountBalance(ctx, account2.GetAddress().String())\n ```\n\nRun the code to test the transfer of tBNB:\n```sh\ngo run account.go\n

    This will output something like:

    2023/09/07 11:18:51 Wair for tx: data:\"\\022&\\n$/cosmos.bank.v1beta1.MsgSendResponse\\032\\010\\000\\000\\000\\000\\000\\000\\372\\235\" log:\"[{\\\"msg_index\\\":0,\\\"events\\\":[{\\\"type\\\":\\\"message\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"action\\\",\\\"value\\\":\\\"/cosmos.bank.v1beta1.MsgSend\\\"},{\\\"key\\\":\\\"sender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"module\\\",\\\"value\\\":\\\"bank\\\"}]},{\\\"type\\\":\\\"coin_spent\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"spender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"amount\\\",\\\"value\\\":\\\"10000000000BNB\\\"}]},{\\\"type\\\":\\\"coin_received\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"receiver\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"amount\\\",\\\"value\\\":\\\"10000000000BNB\\\"}]},{\\\"type\\\":\\\"transfer\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"recipient\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"sender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"amount\\\",\\\"value\\\":\\\"10000000000BNB\\\"}]},{\\\"type\\\":\\\"message\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"sender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"}]}]}]\" gas_wanted:1200 gas_used:1200 events:<type:\"coin_spent\" attributes:<key:\"spender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"6000000000000BNB\" index:true > > events:<type:\"coin_received\" attributes:<key:\"receiver\" value:\"0xf1829676DB577682E944fc3493d451B67Ff3E29F\" index:true > attributes:<key:\"amount\" value:\"6000000000000BNB\" index:true > > events:<type:\"transfer\" attributes:<key:\"recipient\" value:\"0xf1829676DB577682E944fc3493d451B67Ff3E29F\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"6000000000000BNB\" index:true > > events:<type:\"message\" attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > > events:<type:\"tx\" attributes:<key:\"fee\" value:\"6000000000000BNB\" index:true > attributes:<key:\"fee_payer\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > > events:<type:\"tx\" attributes:<key:\"acc_seq\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd/0\" index:true > > events:<type:\"tx\" attributes:<key:\"signature\" value:\"plUsfX6lsI0PLjPfFRY7RvYafQ9GK4gAh3pZHddcMdsR9wJRgKUVJ/JDy4HrIEI+qYHP1bGUOxWExmsVdab0xwE=\" index:true > > events:<type:\"message\" attributes:<key:\"action\" value:\"/cosmos.bank.v1beta1.MsgSend\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"module\" value:\"bank\" index:true > > events:<type:\"coin_spent\" attributes:<key:\"spender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"10000000000BNB\" index:true > > events:<type:\"coin_received\" attributes:<key:\"receiver\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"10000000000BNB\" index:true > > events:<type:\"transfer\" attributes:<key:\"recipient\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"10000000000BNB\" index:true > > events:<type:\"message\" attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > >\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#make-a-storage-deal","title":"Make a storage deal","text":"

    Storing data is one of the most important features of Greenfield. In this section, we\u2019ll walk through the end-to-end process of storing your data on the Greenfield network. We\u2019ll start by importing your data, then make a storage deal with a storage provider, and finally wait for the deal to complete.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#1-create-a-main-file","title":"1. Create a main file","text":"

    Create a storage.go file in your demo project and add the following boilerplate code:

    func main() {\u200b\n  // initialize account\n  account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n  log.Println(\"address info:\", account)\u200b\n  if err != nil {\n    log.Fatalf(\"New account from private key error, %v\", err)\n  }\n\n  //initialize client\n  cli, err := client.New(chainId, rpcAddr, client.Option {DefaultAccount: account})\n  if err != nil {\n    log.Fatalf(\"unable to new greenfield client, %v\", err)\n  }\n\n  ctx := context.Background()\u200b\n\n  // 1. choose storage provider\n  // 2. Create a bucket\n  // 3. Upload your data and set a quota      \u200b\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#2-choose-your-own-sp","title":"2. Choose your own SP","text":"

    You can query the list of SP.

      // get storage providers list\n  spLists, err := cli.ListStorageProviders(ctx, true)\n  if err != nil {\n    log.Fatalf(\"fail to list in service sps\")\n  }\n\n  //choose the first sp to be the primary SP\n  primarySP := spLists[0].GetOperatorAddress()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#3-create-your-bucket","title":"3. Create your bucket","text":"

    Bucket can be private or public. You can customize it with options. * VISIBILITY_TYPE_PUBLIC_READ * VISIBILITY_TYPE_PRIVATE

      chargedQuota := uint64(10000000)\n  visibility := storageTypes.VISIBILITY_TYPE_PUBLIC_READ\n  opts := types.CreateBucketOptions{Visibility: visibility, ChargedQuota: chargedQuota}\n\n  bucketTx, err := cli.CreateBucket(ctx, bucketName, primarySP, opts)\n  if err != nil {\n    log.Fatalf(\"unable to send, %v\", err)\n  }\n  log.Printf(\"Create bucket response: %s\", bucketTx)\n
    To understand how does quota work, read this doc."},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#4-upload-your-object","title":"4. Upload your object","text":"

    Objects can also be private or public. Uploading objects is composed of two parts: create and put. * CreateObject gets an approval of creating an object and sends createObject txn to Greenfield network. * PutObject supports the second stage of uploading the object to bucket.

      // create and put object\n  var buffer bytes.Buffer\n  line := `0123456789`\n  for i := 0; i < objectSize/10; i++ {\n    buffer.WriteString(fmt.Sprintf(\"%s\", line))\n  }\n\n  txnHash, err := cli.CreateObject(ctx, bucketName, objectName, bytes.NewReader(buffer.Bytes()), types.CreateObjectOptions{})\n\n  handleErr(err, \"CreateObject\")\n\n  err = cli.PutObject(ctx, bucketName, objectName, int64(buffer.Len()),\n    bytes.NewReader(buffer.Bytes()), types.PutObjectOptions{TxnHash: txnHash})\n  handleErr(err, \"PutObject\")\n\n  log.Printf(\"object: %s has been uploaded to SP\\n\", objectName)\n\n  waitObjectSeal(cli, bucketName, objectName)\n
      func waitObjectSeal(cli client.Client, bucketName, objectName string) {\n    ctx := context.Background()\n    // wait for the object to be sealed\n    timeout := time.After(15 * time.Second)\n    ticker := time.NewTicker(2 * time.Second)\n\n    for {\n      select {\n      case <-timeout:\n        err := errors.New(\"object not sealed after 15 seconds\")\n        handleErr(err, \"HeadObject\")\n      case <-ticker.C:\n        objectDetail, err := cli.HeadObject(ctx, bucketName, objectName)\n        handleErr(err, \"HeadObject\")\n        if objectDetail.ObjectInfo.GetObjectStatus().String() == \"OBJECT_STATUS_SEALED\" {\n          ticker.Stop()\n          fmt.Printf(\"put object %s successfully \\n\", objectName)\n          return\n        }\n      }\n    }\n  }\n

    The primary SP syncs with secondary SPs to set up the data redundancy, and then it signs a Seal transaction with the finalized metadata for storage. If the primary SP determines that it doesn\u2019t want to store the file due to whatever reason, it can also \u201cSealReject\u201d the request.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#5-object-management","title":"5. Object management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#51-read-object","title":"5.1 Read object","text":"

    You can call GetObject function to download data.

      // get object\n  reader, info, err := cli.GetObject(ctx, bucketName, objectName, types.GetObjectOptions{})\n  handleErr(err, \"GetObject\")\n  log.Printf(\"get object %s successfully, size %d \\n\", info.ObjectName, info.Size)\n  handleErr(err, \"GetObject\")\n  objectBytes, err := io.ReadAll(reader)\n  fmt.Printf(\"Read data: %s\\n\", string(objectBytes))\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#52-update-object-visibility","title":"5.2 Update object visibility","text":"
      //update bucket visibility\n  updateBucketTx, err := cli.UpdateBucketVisibility(ctx, bucketName,\n              storageTypes.VISIBILITY_TYPE_PRIVATE, types.UpdateVisibilityOption{})\n\n  resp, err := cli.WaitForTx(ctx, updateBucketTx)\n  fmt.Printf(\"Update response: %s\\n\", resp)\n  handleErr(err, \"UpdateBucketVisibility\")\n\n  // Update object visibility\n  updateObjectTx, err := cli.UpdateObjectVisibility(ctx, bucketName,objectName,\n              storageTypes.VISIBILITY_TYPE_PRIVATE, types.UpdateObjectOption{})\n\n  resp, err := cli.WaitForTx(ctx, updateObjectTx)\n  fmt.Printf(\"Update response: %s\\n\", resp)\n  handleErr(err, \"UpdateObjectVisibility\")\n ```\n\n#### 5.3 Delete object\nThe function DeleteObject support deleting objects.\n```go\n  // delete object\n  delTx, err := cli.DeleteObject(ctx, bucketName, objectName, types.DeleteObjectOption{})\n  handleErr(err, \"DeleteObject\")\n  _, err = cli.WaitForTx(ctx, delTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n  log.Printf(\"object: %s has been deleted\\n\", objectName)\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#conclusion","title":"Conclusion","text":"

    Congratulations on making it all the way through this tutorial! In this tutorial, we learned the basics of interacting with the Greenfield network using SDK library.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/","title":"Dataset Batch operations - BNB Greenfield File Management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#how-does-batch-object-uploading-work-in-greenfield","title":"How does batch object uploading work in Greenfield?","text":"

    In Greenfield, uploading an object to a bucket is a two-stage process. First, a transaction including the object metadata needs to be broadcasted to the Greenfield Chain and confirmed. After confirmation, PUT the object to a Greenfield Storage Provider. In the first stage, every transaction needs to be signed by the primary key(also known as account, refer to accounts for more details). And if you are accessing Greenfield via front-end app and connecting wallet like Metamask(or other compatible wallets), you will be asked for approval to sign the transaction.

    For people who may have encountered the need to upload large amounts of objets, while uploading objects to Greenfield individually can be a time-consuming and tedious process, because they have to repeatedly approve wallet\u2019s pop-up requests to send transactions, batch uploading can be a quick and efficient solution to this problem.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#ways-to-perform-batch-uploading","title":"Ways to Perform Batch Uploading","text":"

    We would introduce two ways to achive the purpose of batch uploading:

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#multi-message","title":"Multi-Message.","text":"

    Greenfield supports supports embedding multiple messages in a single transaction. You can create a transaction with multiple MsgCreateObject messages and broadcast it to the Greenfield Chain. Once the object metadata is confirmed on-chain, you can start PUTting the objects to the Storage Provider. However, please note that this approach may not be suitable for very large batches due to transaction size limitations in Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#temporary-account","title":"Temporary Account.","text":"

    Create a temporary account at runtime and grant it full permissions to create objects on behalf of your primary account. In this approach, your primary account only needs to send a transaction to Greenfield to grant permissions to the temporary account. For each object to be uploaded, the temporary account will be used to broadcast the transaction to the Greenfield Chain. There is no further interaction required from the primary account. Please note, the temporary account does not need to be deposited.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#bundle-service","title":"Bundle Service","text":"

    Storing small files in Greenfield is inefficient due to the metadata stored on the blockchain being larger than the files themselves. This leads to higher costs for users. Additionally, Greenfield Blockchain has a capacity limit for processing files simultaneously.

    To address this issue, we have proposed BEP-323: Bundle Format For Greenfield. This repository contains the Golang version of the bundle format, which guides users on aggregating objects into a bundle and parsing a bundled object into separate objects.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#temporary-account-showcase","title":"Temporary Account Showcase","text":"

    To demonstrate the batch uploading process using the Temporary Account approach, an example is provided using the Greenfield-go-sdk. The example includes steps to create a bucket for object storage, generate a temporary account, grant permissions to the temporary account, and create and PUT objects.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#create-a-bucket-for-object-storage","title":"Create a bucket for object storage.","text":"

    Before we get started, we would need to create a bucket to hold objects using the primary account. This requires broadcasting a transaction to Greenfield. The code below shows how to fill in the CreateBucket request with the bucket name and selected Storage Provider that will serve our bucket, after the transaction is sent, you might want to check the bucket\u2019s existence to confirm its creation.

    primaryAccount, _ := types.NewAccountFromPrivateKey(\"primaryAccount\", privateKey)\ncli, _ := client.New(chainId, rpcAddr, client.Option{DefaultAccount: primaryAccount})\nctx := context.Background()\n// get storage providers list\nisInService := true\nspLists, _ := cli.ListStorageProviders(ctx, isInService)\n// choose the first sp to be the primary SP, you are free to choose any other one\nprimarySP := spLists[0].GetOperatorAddress()\n// sends a request to Greenfield to create a bucket.\ncli.CreateBucket(ctx, \"yourBucketName\", primarySP, types.CreateBucketOptions{})\n// wait for confirmation\ntime.Sleep(3 * time.Second)\n// get bucket meta data from Greenfield\nbucketInfo, _ := cli.HeadBucket(ctx, \"yourBucketName\")\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#temporary-account-generation","title":"Temporary account generation","text":"

    Once the bucket is created, we can start generating the temporary account. A private key is 32 bytes represented as a 64 hexadecimal character string. We can create any random 64 hexadecimal character string to form a private key. However, in that case, we won\u2019t be able to recover it and reuse in the future. So, it is more preferred to use a designed payload to generate the private key. In the code snippet below, we concatenate a signPayload by string \u201cpayload\u201d and the account sequence, We then use the signature signed by our primary account to form a newly created private key. The signPayload acts like a password. No matter what manipulation is applied to the signPayload to generate the signature, as long as we remember the signPayload, we can always retrieve the private key by applying the same manipulation again. The example shown here is just one way to get the signature and used for new temporary priavte key, but you are free to use any other algorithm.

    // generate the temp account using user's primary account signing on payload decided by user, here we add the account nonce to be part of sign payload\nsignPayload := fmt.Sprintf(\"payload%d\", primaryAccount.GetSequence())\ntempAcct, _ := genTemporaryAccount(primaryAccount, signPayload)\ntempAcctAddr, _ := tempAcct.GetAddress().Marshal()\n
    // genTemporaryAccount generates a temporary account, the signPayload is to be signed by user's own private key(Primary account),\n// and the signature is used to generate the temporary account's private key.\n// User can reconvert account with the signPayload at any time\nfunc genTemporaryAccount(acct *types.Account, signPayload string) (*types.Account, error) {\n    signBz := []byte(signPayload)\n    sig, err := acct.Sign(tmhash.Sum(signBz))\n    if err != nil {\n    return nil, err\n    }\n    if len(sig) < privateKeyLength {\n    return nil, fmt.Errorf(\"required signature lenght is no less than %d, cur lenght %d\", privateKeyLength, len(sig))\n    }\n    return types.NewAccountFromPrivateKey(\"temp\", hex.EncodeToString(sig[:privateKeyLength]))\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#grant-temporary-account-permissions","title":"Grant temporary account permissions","text":"

    To entitle the temporary account to create objects on behalf of the primary account, two types of permissions are required. Both need to be granted by the primary account: - Grant the creating object permission in the bucket. Policy defines that the operation that can be enforced on a resource by an account or a group. Refer to permission to get more details - Grant an allowance so that the gas fee will be deducted from the primary account, and the primary account will be the owner of objects.

    Again, we would need to broadcast transaction including these two types of granting messages to Greenfield using the primary account.

    // Grant the temporary account creating objects permission in the primary account's bucket\nstatement := &permTypes.Statement{\n    Actions: []permTypes.ActionType{permTypes.ACTION_CREATE_OBJECT},\n    Effect:  permTypes.EFFECT_ALLOW,\n}\nmsgPutPolicy := storageTypes.NewMsgPutPolicy(primaryAccount.GetAddress(), gnfdTypes.NewBucketGRN(\"yourBucketName\").String(), \n    permTypes.NewPrincipalWithAccount(tempAcct.GetAddress()), []*permTypes.Statement{statement}, nil)\n\n// Grant allowance to the temporary account to broadcast the expected transaction type\nallowedMsg := make([]string, 0)\nallowedMsg = append(allowedMsg, \"/greenfield.storage.MsgCreateObject\")\nallowance, _ := feegrant.NewAllowedMsgAllowance(&feegrant.BasicAllowance{}, allowedMsg)\nmsgGrantAllowance, _ := feegrant.NewMsgGrantAllowance(allowance, primaryAccount.GetAddress(), tempAcct.GetAddress())\n\n// Broadcast the transaction to Greenfield\ncli.BroadcastTx(ctx, []sdk.Msg{msgGrantAllowance, msgPutPolicy}, types.TxOption{})\n\n// Wait for a block and confirm that permissions are granted\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#create-object-meta-and-put-object","title":"Create object meta and put object","text":"

    Finally, you can create the object metadata and put the object using the temporary account:

    // Switch to use the temporary account\ncli.SetDefaultAccount(tempAcct)\n// Define the primary account as the granter\ntxOpt := types.TxOption{FeeGranter: primaryAccount.GetAddress()}\n// create object content\nvar buffer bytes.Buffer\nline := `0123456789`\nfor i := 0; i < 100; i++ {\n    buffer.WriteString(fmt.Sprintf(\"%s\", line))\n}\n// Create the object meta on Greenfield Chain\ncli.CreateObject(ctx, \"yourBucketName\", \"yourObjectName\", bytes.NewReader(buffer.Bytes()), types.CreateObjectOptions{TxOpts: &txOpt})\n// Wait for a block, once the meta is created on the chain, upload the object to the Greenfield Storage Provider\ntime.Sleep(3 * time.Second)\n// Upload the object to Greenfield Storage Provider\ncli.PutObject(ctx, \"yourBucketName\", \"yourObjectName\", int64(buffer.Len()), bytes.NewReader(buffer.Bytes()), types.PutObjectOptions{})\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#bundle-service-example","title":"Bundle Service Example","text":"

    Here is the guide for how to aggregate batch objects as a bundle, and how to parse a bundled object. As for how to interact with Greenfield, you should refer to \u3010Greenfield GO SDK](https://github.com/bnb-chain/greenfield-go-sdk).

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#aggregate-various-objects-as-bundle","title":"Aggregate various objects as bundle","text":"

    Follow the steps below to aggregate multiple objects into a single bundle.

    1. Use the NewBundlefunction to create an empty bundle.
    // Assemble above two objects into a bundle object\n    bundle, err := bundle.NewBundle()\n    handleErr(err, \"NewBundle\")\n
    1. Use the bundle\u2019s AppendObject method to add objects to the bundle individually.

          _, err = bundle.AppendObject(\"object1\", bytes.NewReader(buffer1.Bytes()), nil)\n    handleErr(err, \"AppendObject\")\n    _, err = bundle.AppendObject(\"object2\", bytes.NewReader(buffer2.Bytes()), nil)\n    handleErr(err, \"AppendObject\")\n
    2. Use the bundle\u2019s FinalizeBundle method to seal the bundle, preventing any further objects from being added.

          bundledObject, totalSize, err := bundle.FinalizeBundle()\n    handleErr(err, \"FinalizeBundle\")\n
    3. To release resources after use, utilize the Close method of the bundle.

       defer bundle.Close()\n

    Full example here

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#extract-objects-from-bundled-object","title":"Extract objects from bundled object","text":"

    Follow the steps below to extract various objects from a bundle.

    1. Open the bundled object as a bundle instance using NewBundleFromFile.
      // Extract objects from bundled object\n    bundle, err := bundle.NewBundleFromFile(bundleFile.Name())\n    handleErr(err, \"NewBundleFromFile\")\n
    2. Retrieve all the objects\u2019 meta within the bundle using the bundle\u2019s GetBundleObjectsMeta method.
      // Extract objects from bundled object\n    objMeta, err := bundle.GetBundleObjectsMeta(bundleFile.Name())\n    handleErr(err, \"GetBundleObjectsMeta\")\n
    3. Access various objects one by one using the bundle\u2019s GetObject method.

          obj1, size, err := bundle.GetObject(\"object1\")\n    if err != nil || obj1 == nil || size != singleObjectSize {\n        handleErr(fmt.Errorf(\"parse object1 in bundled object failed: %v\", err), \"GetObject\")\n    }\n    obj2, size, err := bundle.GetObject(\"object2\")\n    if err != nil || obj2 == nil || size != singleObjectSize {\n        handleErr(fmt.Errorf(\"parse object2 in bundled object failed: %v\", err), \"GetObject\")\n    }\n
    4. To release resources after use, utilize the Close method of the bundle.

       defer bundle.Close()\n

    Full example here

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/","title":"Simple Tool for File Management (JS) - BNB Greenfield File Management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#building-file-management-tool-with-greenfield-sdk-js","title":"Building File Management Tool with Greenfield SDK (JS)","text":"

    Several Chain API libraries are available. These libraries manage the low-level logic of connecting to the Greenfield node, making requests, and handing the responses.

    In this tutorial, we\u2019ll use the JS-SDK library to interact with testnet.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#prerequisites","title":"Prerequisites","text":"

    Before getting started, you should be familiar with:

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#setup","title":"Setup","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#create-project","title":"Create Project","text":"BrowserNodejs

    Follow Quick Start to create the project.

    Create a new index.js:

    ```bash title=\"Nodejs create project\"\n> mkdir gnfd-app\n> cd gnfd-app\n> touch index.js\n```\n\nInstall SDK:\n\n```bash title=\"npm install deps\"\n> npm init -y\n> npm add @bnb-chain/greenfield-js-sdk\n```\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#create-greenfield-client","title":"Create Greenfield Client","text":"BrowserNodejs Create testnet Client
    import { Client } from '@bnb-chain/greenfield-js-sdk';\n\nconst client = Client.create('https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org, '5600');\n
    Create testnet client
    const {Client}  = require('@bnb-chain/greenfield-js-sdk');\n\n// testnet\nconst client = Client.create('https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org', '5600');\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#test-a-simple-function","title":"Test a simple function","text":"BrowserNodejs
    <button\nclassName=\"button is-primary\"\nonClick={async () => {\n    const latestBlockHeight = await client.basic.getLatestBlockHeight();\n\n    alert(JSON.stringify(latestBlockHeight));\n}}\n>\ngetLatestBlockHeight\n</button>\n
    index.js
    ;(async () => {\nconst latestBlockHeight = await client.basic.getLatestBlockHeight()\n\nconsole.log('latestBlockHeight', latestBlockHeight)\n})()\n

    Run index.js to get the latest block height:

    > node index.js\n

    This will output like:

    latestBlockHeight 3494585\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#get-address-balance","title":"Get Address balance","text":"

    In the previous step, we verified that the client was OK.

    Now we try more features for an account.

    BrowserNodejs
    <button\nclassName=\"button is-primary\"\nonClick={async () => {\n    if (!address) return;\n\n    const balance = await client.account.getAccountBalance({\n    address: address,\n    denom: 'BNB',\n    });\n\n    alert(JSON.stringify(balance));\n}}\n>\ngetAccountBalance\n</button>\n

    You can query an account\u2019s balance by calling account.getAccountBalance function.

    get account's balance
    ;(async () => {\n    const balance = await client.account.getAccountBalance({\n    address: '0x1C893441AB6c1A75E01887087ea508bE8e07AAae',\n    denom: 'BNB'\n})\n\nconsole.log('balance: ', balance)\n})()\n

    Run node index.js to get the account\u2019s balance:

    balance: { balance: { denom: 'BNB', amount: '4804586044359520195' } }\n

    Apart from the basic data queries shown above, there are many more features. Please see the API Reference for all Greenfield API definitions.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#manage-wallet","title":"Manage Wallet","text":"

    The wallet in Nodejs is generated by a private key, but the wallet plugin(MetaMask, CollectWallet, etc) can\u2019t get the user\u2019s private key in the browser, so another way is needed.

    BrowserNodejs
    <button\nclassName=\"button is-primary\"\nonClick={async () => {\n    if (!address) return;\n\n    const transferTx = await client.account.transfer({\n    fromAddress: address,\n    toAddress: '0x0000000000000000000000000000000000000000',\n    amount: [\n        {\n        denom: 'BNB',\n        amount: '1000000000',\n        },\n    ],\n    });\n\n    const simulateInfo = await transferTx.simulate({\n    denom: 'BNB',\n    });\n\n    const res = await transferTx.broadcast({\n    denom: 'BNB',\n    gasLimit: Number(simulateInfo.gasLimit),\n    gasPrice: simulateInfo.gasPrice,\n    payer: address,\n    granter: '',\n    signTypedDataCallback: async (addr: string, message: string) => {\n        const provider = await connector?.getProvider();\n        return await provider?.request({\n        method: 'eth_signTypedData_v4',\n        params: [addr, message],\n        });\n    },\n    });\n\n    if (res.code === 0) {\n    alert('transfer success!!');\n    }\n}}\n>\ntransfer\n</button>\n

    In general, we need to put the private key in the .env file and ignore this file in the .gitignore file (for account security).

    > touch .env\n

    Add this information to .env:

    # fill your account info\nACCOUNT_PRIVATEKEY=0x...\nACCOUNT_ADDRESS=0x...\n

    Install dotenv dependencies(for loading variables from .env):

    > npm install dotenv\n

    Everything is ready and we can transfer the transaction now.

    Create transfer.js file:

    transfer.js
    require('dotenv').config();\nconst {Client} = require('@bnb-chain/greenfield-js-sdk');\nconst client = Client.create('https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org', '5600');\n\n;(async () => {\n\n// construct tx\nconst transferTx = await client.account.transfer({\n    fromAddress: process.env.ACCOUNT_ADDRESS,\n    toAddress: '0x0000000000000000000000000000000000000000',\n    amount: [\n    {\n        denom: 'BNB',\n        amount: '1000000000',\n    },\n    ],\n})\n\n// simulate transfer tx\nconst simulateInfo = await transferTx.simulate({\n    denom: 'BNB',\n});\n\n// broadcast transfer tx\nconst res = await transferTx.broadcast({\n    denom: 'BNB',\n    gasLimit: Number(simulateInfo.gasLimit),\n    gasPrice: simulateInfo.gasPrice,\n    payer: process.env.ACCOUNT_ADDRESS,\n    granter: '',\n    privateKey: process.env.ACCOUNT_PRIVATEKEY,\n})\n\nconsole.log('res', res)\n})()\n

    Running node transfer.js:

    transfer tx response

    {\ncode: 0,\nheight: 3495211,\ntxIndex: 0,\nevents: [\n    { type: 'coin_spent', attributes: [Array] },\n    { type: 'coin_received', attributes: [Array] },\n    { type: 'transfer', attributes: [Array] },\n    { type: 'message', attributes: [Array] },\n    { type: 'tx', attributes: [Array] },\n    { type: 'tx', attributes: [Array] },\n    { type: 'tx', attributes: [Array] },\n    { type: 'message', attributes: [Array] },\n    { type: 'coin_spent', attributes: [Array] },\n    { type: 'coin_received', attributes: [Array] },\n    { type: 'transfer', attributes: [Array] },\n    { type: 'message', attributes: [Array] }\n],\nrawLog: '[{\"msg_index\":0,\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"/cosmos.bank.v1beta1.MsgSend\"},{\"key\":\"sender\",\"value\":\"0x1C893441AB6c1A75E01887087ea508bE8e07AAae\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"coin_spent\",\"attributes\":[{\"key\":\"spender\",\"value\":\"0x1C893441AB6c1A75E01887087ea508bE8e07AAae\"},{\"key\":\"amount\",\"value\":\"1000000000BNB\"}]},{\"type\":\"coin_received\",\"attributes\":[{\"key\":\"receiver\",\"value\":\"0x0000000000000000000000000000000000000000\"},{\"key\":\"amount\",\"value\":\"1000000000BNB\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"0x0000000000000000000000000000000000000000\"},{\"key\":\"sender\",\"value\":\"0x1C893441AB6c1A75E01887087ea508bE8e07AAae\"},{\"key\":\"amount\",\"value\":\"1000000000BNB\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"0x1C893441AB6c1A75E01887087ea508bE8e07AAae\"}]}]}]',\ntransactionHash: '1B731E99A55868F773E9A7C951D9325BE7995616B990924D47491320599789DE',\nmsgResponses: [\n    {\n    typeUrl: '/cosmos.bank.v1beta1.MsgSendResponse',\n    value: Uint8Array(0) []\n    }\n],\ngasUsed: 1200n,\ngasWanted: 1200n\n}\n

    More TxClient References.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#make-a-storage-deal","title":"Make a storage deal","text":"

    Storing data is one of the most important features of Greenfield. In this section, we\u2019ll walk through the end-to-end process of storing your data on the Greenfield network. We\u2019ll start by importing your data, then make a storage deal with a storage provider, and finally wait for the deal to complete.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#0-create-the-main-file","title":"0. Create the main file","text":"BrowserNodejs

    The browser doesn\u2019t need the main file.

    > touch storage.js\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#1-choose-your-own-sp","title":"1. Choose your own SP","text":"

    You can query the list of SP:

    BrowserNodejs utils/offchainAuth.ts
    export const getSps = async () => {\nconst sps = await client.sp.getStorageProviders();\nconst finalSps = (sps ?? []).filter((v: any) => v.endpoint.includes('nodereal'));\n\nreturn finalSps;\n};\n\nexport const getAllSps = async () => {\nconst sps = await getSps();\n\nreturn sps.map((sp) => {\n    return {\n    address: sp.operatorAddress,\n    endpoint: sp.endpoint,\n    name: sp.description?.moniker,\n    };\n});\n};\n\nexport const selectSp = async () => {\nconst finalSps = await getSps();\n\nconst selectIndex = Math.floor(Math.random() * finalSps.length);\n\nconst secondarySpAddresses = [\n    ...finalSps.slice(0, selectIndex),\n    ...finalSps.slice(selectIndex + 1),\n].map((item) => item.operatorAddress);\nconst selectSpInfo = {\n    id: finalSps[selectIndex].id,\n    endpoint: finalSps[selectIndex].endpoint,\n    primarySpAddress: finalSps[selectIndex]?.operatorAddress,\n    sealAddress: finalSps[selectIndex].sealAddress,\n    secondarySpAddresses,\n};\n\nreturn selectSpInfo;\n};\n\nconst getOffchainAuthKeys = async (address: string, provider: any) => {\nconst storageResStr = localStorage.getItem(address);\n\nif (storageResStr) {\n    const storageRes = JSON.parse(storageResStr) as IReturnOffChainAuthKeyPairAndUpload;\n    if (storageRes.expirationTime < Date.now()) {\n    alert('Your auth key has expired, please generate a new one');\n    localStorage.removeItem(address);\n    return;\n    }\n\n    return storageRes;\n}\n\nconst allSps = await getAllSps();\nconst offchainAuthRes = await client.offchainauth.genOffChainAuthKeyPairAndUpload(\n    {\n    sps: allSps,\n    chainId: GREEN_CHAIN_ID,\n    expirationMs: 5 * 24 * 60 * 60 * 1000,\n    domain: window.location.origin,\n    address,\n    },\n    provider,\n);\n\nconst { code, body: offChainData } = offchainAuthRes;\nif (code !== 0 || !offChainData) {\n    throw offchainAuthRes;\n}\n\nlocalStorage.setItem(address, JSON.stringify(offChainData));\nreturn offChainData;\n};\n
    storage.js
    ;(async () => {\n// get storage providers list\nconst sps = await client.sp.getStorageProviders()\n\n// choose the first up to be the primary SP\nconst primarySP = sps[0].operatorAddress;\n})()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#2-create-your-bucket","title":"2. Create your bucket","text":"

    Bucket can be private or public. You can customize it with options.

    VisibilityType:

    create bucket
    import { Long, VisibilityType, RedundancyType, bytesFromBase64 } from '@bnb-chain/greenfield-js-sdk';\nconst createBucketTx = await client.bucket.createBucket(\n  {\n    bucketName: info.bucketName,\n    creator: address,\n    visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,\n    chargedReadQuota: Long.fromString('0'),\n    primarySpAddress: spInfo.primarySpAddress,\n    paymentAddress: address,\n  },\n);\n\nconst simulateInfo = await createBucketTx.simulate({\n  denom: 'BNB',\n});\n\nconsole.log('simulateInfo', simulateInfo);\n\nconst res = await createBucketTx.broadcast({\n  denom: 'BNB',\n  gasLimit: Number(simulateInfo?.gasLimit),\n  gasPrice: simulateInfo?.gasPrice || '5000000000',\n  payer: address,\n  granter: '',\n});\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#3-create-object-and-upload-object","title":"3. Create Object and Upload Object","text":"

    Objects can also be private or public.

    Getting the file\u2019s checksum needs reed-solomon:

    BrowserNodejs
    import { ReedSolomon } from '@bnb-chain/reed-solomon';\n\nconst rs = new ReedSolomon();\n\n// file is File type\nconst fileBytes = await file.arrayBuffer();\nconst expectCheckSums = rs.encode(new Uint8Array(fileBytes));\n
    const fs = require('node:fs');\nconst { NodeAdapterReedSolomon } = require('@bnb-chain/reed-solomon/node.adapter');\n\nconst filePath = './CHANGELOG.md';\nconst fileBuffer = fs.readFileSync(filePath);\nconst rs = new NodeAdapterReedSolomon();\nconst expectCheckSums = await rs.encodeInWorker(__filename, Uint8Array.from(fileBuffer));\n

    Getting approval of creating an object and sending createObject txn to the Greenfield network:

    const createObjectTx = await client.object.createObject(\n  {\n    bucketName: info.bucketName,\n    objectName: info.objectName,\n    creator: address,\n    visibility: VisibilityType.VISIBILITY_TYPE_PRIVATE,\n    contentType: fileType,\n    redundancyType: RedundancyType.REDUNDANCY_EC_TYPE,\n    payloadSize: Long.fromInt(fileBuffer.length),\n    expectChecksums: expectCheckSums.map((x) => bytesFromBase64(x)),\n  },\n);\n\nconst simulateInfo = await createObjectTx.simulate({\n  denom: 'BNB',\n});\n\nconst res = await createObjectTx.broadcast({\n  denom: 'BNB',\n  gasLimit: Number(simulateInfo?.gasLimit),\n  gasPrice: simulateInfo?.gasPrice || '5000000000',\n  payer: address,\n  granter: '',\n});\n

    Upload Object:

    BrowserNodejs
    await client.object.uploadObject(\n{\n    bucketName: info.bucketName,\n    objectName: info.objectName,\n    body: info.file,\n    txnHash: txnHash,\n},\n{\n    type: 'EDDSA',\n    domain: window.location.origin,\n    seed: offChainData.seedString,\n    address,\n},\n);\n
    await client.object.uploadObject(\n{\n    bucketName: bucketName,\n    objectName: objectName,\n    body: createFile(filePath),\n    txnHash: createObjectTxRes.transactionHash,\n},\n{\n    type: 'ECDSA',\n    privateKey: ACCOUNT_PRIVATEKEY,\n}\n);\n\n// convert buffer to file\nfunction createFile(path) {\nconst stats = fs.statSync(path);\nconst fileSize = stats.size;\n\nreturn {\n    name: path,\n    type: '',\n    size: fileSize,\n    content: fs.readFileSync(path),\n}\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#4-object-management","title":"4. Object management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#41-download-object","title":"4.1 Download object","text":"BrowserNodejs
    await client.object.downloadFile(\n{\n    bucketName: info.bucketName,\n    objectName: info.objectName,\n},\n{\n    type: 'EDDSA',\n    address,\n    domain: window.location.origin,\n    seed: offChainData.seedString,\n},\n);\n
    manage.js
    ;(async () => {\n\n// download object\nconst res = await client.object.getObject({\n    bucketName: 'extfkdcxxd',\n    objectName: 'yhulwcfxye'\n}, {\n    type: 'ECDSA',\n    privateKey: ACCOUNT_PRIVATEKEY,\n})\n\n// res.body is Blob\nconsole.log('res', res)\nconst buffer = Buffer.from([res.body]);\nfs.writeFileSync('your_output_file', buffer)\n})()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#42-update-object-visibility","title":"4.2 Update object visibility","text":"BrowserNodejs
    const tx = await client.object.updateObjectInfo({\nbucketName: info.bucketName,\nobjectName: info.objectName,\noperator: address,\nvisibility: 1,\n});\n\nconst simulateTx = await tx.simulate({\ndenom: 'BNB',\n});\n\nconst res = await tx.broadcast({\ndenom: 'BNB',\ngasLimit: Number(simulateTx?.gasLimit),\ngasPrice: simulateTx?.gasPrice || '5000000000',\npayer: address,\ngranter: '',\n});\n
    const tx = await client.object.updateObjectInfo({\nbucketName: 'extfkdcxxd',\nobjectName: 'yhulwcfxye',\noperator: ACCOUNT_ADDRESS,\nvisibility: 1,\n})\n\nconst simulateTx = await tx.simulate({\ndenom: 'BNB',\n})\n\nconst createObjectTxRes = await tx.broadcast({\ndenom: 'BNB',\ngasLimit: Number(simulateTx?.gasLimit),\ngasPrice: simulateTx?.gasPrice || '5000000000',\npayer: ACCOUNT_ADDRESS,\ngranter: '',\nprivateKey: ACCOUNT_PRIVATEKEY,\n});\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#43-delete-object","title":"4.3 Delete Object","text":"BrowserNodejs
    const tx = await client.object.deleteObject({\nbucketName: info.bucketName,\nobjectName: info.objectName,\noperator: address,\n});\n\nconst simulateTx = await tx.simulate({\ndenom: 'BNB',\n});\n\nconst res = await tx.broadcast({\ndenom: 'BNB',\ngasLimit: Number(simulateTx?.gasLimit),\ngasPrice: simulateTx?.gasPrice || '5000000000',\npayer: address,\ngranter: '',\n});\n
    ;(async () => {\nconst tx = await client.object.deleteObject({\n    bucketName: 'extfkdcxxd',\n    objectName: 'yhulwcfxye',\n    operator: ACCOUNT_ADDRESS,\n});\n\nconst simulateTx = await tx.simulate({\n    denom: 'BNB',\n})\n\nconst createObjectTxRes = await tx.broadcast({\n    denom: 'BNB',\n    gasLimit: Number(simulateTx?.gasLimit),\n    gasPrice: simulateTx?.gasPrice || '5000000000',\n    payer: ACCOUNT_ADDRESS,\n    granter: '',\n    privateKey: ACCOUNT_PRIVATEKEY,\n});\n\nif (createObjectTxRes.code === 0) {\n    console.log('delete object success')\n}\n})()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#conclusion","title":"Conclusion","text":"

    Congratulations on making it through this tutorial! In this tutorial, we learned the basics of interacting with the Greenfield network using the SDK library.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#tutorials-source-code","title":"Tutorials Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/","title":"Resumable Upload/Download Demo - BNB Greenfield File Management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#resumable-upload-resumable-download","title":"Resumable Upload & Resumable Download","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#resumable-upload","title":"Resumable Upload","text":"

    Resumable upload refers to the process of uploading a file in multiple parts, where each chunk is uploaded separately.This allows the upload to be resumed from where it left off in case of interruptions or failures, rather than starting the entire upload process from the beginning.

    During resumable upload, if an error occurs during the PutObject operation, the subsequent upload attempts will first query the server-side for the progress of the previous upload. It will then resume the upload from the last offset.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#upload-process-overview","title":"Upload Process Overview","text":"
    1. Start the initial PutObject operation to upload the object.
    2. If an error occurs during the upload, such as a network interruption or server error, the upload process is interrupted.
    3. When resuming the upload, the next PutObject operation will initiate a query to the server to retrieve the progress of the previous upload.
    4. The server responds with the last offset from which the upload needs to resume.
    5. The PutObject operation resumes the upload from offset received from the server.
    6. The upload process continues from the point of interruption until completion.
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#putobject-options","title":"PutObject Options","text":"

    The PutObject operation in the Greenfield GO-SDK API allows you to upload an object to a bucket. It provides additional options for configuration through the PutObjectOptions struct. This document describes two new options introduced in the PutObjectOptions struct.

    indicate the resumable upload \u2018s part size, uploading a large file in multiple parts. The part size is an integer multiple of the segment size.

    indicate whether need to enable resumeable upload. Resumable upload refers to the process of uploading a file in multiple parts, where each part is uploaded separately.This allows the upload to be resumed from where it left off in case of interruptions or failures, rather than starting the entire upload process from the beginning.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#usage-example","title":"Usage Example","text":"
    var buffer bytes.Buffer\nerr := s.Client.PutObject(\n    ctx,\n    bucketName,\n    objectName,\n    int64(buffer.Len()),\n    bytes.NewReader(buffer.Bytes()),\n    types.PutObjectOptions{\n        PartSize:        1024 * 1024 * 16, // 16 MB\n        DisableResumable: false,\n    },\n)\n

    In the above example, we create a bytes.Buffer named buffer to hold the object data. We then use the PutObject operation to upload the object to the specified bucket and object name. The PutObjectOptions struct is passed with the desired options set. In this case, the PartSize is set to the default value of 16 MB, and the DisableResumable is set to false to enable resumable upload.

    Note: Make sure to replace the placeholder values (s.Client, s.ClientContext, bucketName, and objectName) with the actual variables or values relevant to your code.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#resumable-download","title":"Resumable Download","text":"

    The FGetObjectResumable function in the S3 Client API allows you to perform resumable downloads for large files. This function downloads a file from the specified bucket and object name to a local file, with the ability to resume the download in case of errors or interruptions.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#download-process-overview","title":"Download Process Overview","text":"
    1. Start the initial FGetObjectResumable function to download the file.
    2. During the download process, the function retrieves segments of the file from the server-side and appends them to an object_{operatoraddress}{getrange}.tmp file.
    3. If an error occurs during the download, such as a network interruption or server error, the download process is interrupted.
    4. When resuming the download, the subsequent FGetObjectResumable function first checks if the object_{operatoraddress}{getrange}.tmp file exists.
    5. If the object_{operatoraddress}{getrange}.tmp file exists, the function verifies the checksum to ensure the integrity of the partially downloaded file.
    6. If the object_{operatoraddress}{getrange}.tmp file does not exist or the checksum is invalid, the function starts a fresh download of the object from the server.
    7. The download process continues from the last offset, and appending the segments to the object_{operatoraddress}{getrange}.tmp file.
    8. Once the download is complete, the object_{operatoraddress}{getrange}.tmp file can be renamed or processed as needed.
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#usage-example_1","title":"Usage Example","text":"
    err = s.Client.FGetObjectResumable(\n    s.ClientContext,\n    bucketName,\n    objectName,\n    newFile,\n    types.GetObjectOptions{},\n)\n

    In the above example, the FGetObjectResumable function is used to perform a resumable download of a file from the specified bucket and object name. If an error occurs during the download, the subsequent function calls will check the existence and validity of the object_{operatoraddress}{getrange}.tmp file, and resume the download from the last offset.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#source-code","title":"Source code","text":""},{"location":"bnb-greenfield/for-validator/overview/","title":"Overview - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-validator/overview/#overview","title":"Overview","text":""},{"location":"bnb-greenfield/for-validator/overview/#what-is-the-greenfield-blockchain","title":"What is the Greenfield Blockchain","text":"

    The Greenfield blockchain plays a pivotal role in the Greenfield ecosystem. It forms the core of the platform and is constructed on the Cosmos/Tendermint infrastructure. Within the Greenfield blockchain, there are two categories of states that exist on-chain:

    Transactions conducted on the Greenfield blockchain can alter the aforementioned states. These states and transactions make up the majority of the BNB Greenfield economic data.

    "},{"location":"bnb-greenfield/for-validator/overview/#how-greenfield-blockchain-works","title":"How Greenfield Blockchain Works","text":"

    The Greenfield Blockchain utilizes the Tendermint consensus mechanism, implementing a Proof-of-Stake approach to ensure network security. Validator election and governance are managed through a proposal-vote mechanism, following the governance module of Cosmos SDK. Greenfield\u2019s validators produce blocks every 2 seconds.

    As for the blockchain\u2019s native token, BNB serves as both gas and governance token. The initial BNB is locked on BNB Smart Chain (BSC) and subsequently re-minted on Greenfield. Cross-chain communication enables smooth flow of BNB and data operation primitives between Greenfield and BSC. The total circulation of BNB remains unaffected and will continue moving along the BNB Beacon Chain, BSC, and Greenfield.

    Tip

    Here is a good reading about the working principles of an application chain built on Tendermint.

    "},{"location":"bnb-greenfield/for-validator/overview/#validator-from-greenfield-blockchain","title":"Validator from Greenfield Blockchain","text":"

    The validators of the Greenfield Blockchain are integral to the network\u2019s security and reliability. However, their responsibilities extend well beyond that:

    1. Validators are tasked with achieving consensus on cross-chain events and relaying cross-chain packets to both Greenfield and BNB Smart Chain. This ensures that cross-chain transactions are executed quickly, securely, and with minimal cost.

    2. Validators play a key role in ensuring the integrity and availability of data provided by service providers (SPs). By challenging the data availability of SPs in a specific or random manner, validators can weed out malicious actors and those who provide subpar services. Punishing such actors through appropriate measures - such as slashing their stake, for example - helps to ensure the quality and reliability of services in the Greenfield ecosystem.

    3. Validators also have a say in the governance of the network. They vote on issues related to the future development of Greenfield\u2019s ecosystem and adjust various network parameters as necessary. This ensures that the network remains healthy and sustainable over time, while accommodating the changing needs and demands of its users.

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/","title":"Become Validator","text":""},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#become-validator","title":"Become Validator","text":""},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#minimum-requirements","title":"Minimum Requirements","text":""},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#setting-up-validator-node","title":"Setting up Validator Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#1-install-fullnode","title":"1. Install Fullnode","text":"

    Follow the instructions here to set up a full node.

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#2-prepare-validator-delegator-validator-bls-relayer-and-challenger-accounts","title":"2. Prepare validator, delegator, validator BLS, relayer, and challenger accounts","text":"

    Warning

    The current key generation and storage procedures are not very secure. It is highly recommended to implement a more robust method, particularly when dealing with keys like the delegator and operator keys.

    For enhanced security and best practices, the usage of the Cold Wallet and MPC Wallet is strongly encouraged.

    Note

    The keyring-backend supports multiple storage backends, some of which may not be available on all operating systems. See more details here.

    gnfd keys add validator --keyring-backend test\ngnfd keys add delegator --keyring-backend test\ngnfd keys add validator_bls --keyring-backend test --algo eth_bls\ngnfd keys add validator_relayer --keyring-backend test\ngnfd keys add validator_challenger --keyring-backend test\n

    Tip

    Alternatively, if you choose a different $KEY_HOME location and you are not using the suggested default ~/.gnfd, you may start the full node by using below script, where $KEY_HOME is your selected directory.

    gnfd keys add validator --keyring-backend test --home ${KEY_HOME}\ngnfd keys add delegator --keyring-backend test --home ${KEY_HOME}\ngnfd keys add validator_bls --keyring-backend test --algo eth_bls --home ${KEY_HOME}\ngnfd keys add validator_relayer --keyring-backend test --home ${KEY_HOME}\ngnfd keys add validator_challenger --keyring-backend test --home ${KEY_HOME}\n
    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#3-obtain-validator-delegator-validator-bls-relayer-and-challenger-account-addresses","title":"3. Obtain validator, delegator, validator BLS, relayer, and challenger account addresses","text":"

    Note

    Ensure you choose the correct \u2013keyring-backend and that \u2013home is set correctly if you saved the files in a custom folder in step 2.

    VALIDATOR_ADDR=$(gnfd keys show validator -a --keyring-backend test)\nDELEGATOR_ADDR=$(gnfd keys show delegator -a --keyring-backend test)\nRELAYER_ADDR=$(gnfd keys show validator_relayer -a --keyring-backend test)\nCHALLENGER_ADDR=$(gnfd keys show validator_challenger -a --keyring-backend test)\nVALIDATOR_BLS=$(gnfd keys show validator_bls --keyring-backend test --output json | jq -r '.pubkey_hex')\nVALIDATOR_BLS_PROOF=$(gnfd keys sign ${VALIDATOR_BLS} --keyring-backend test --from validator_bls)\nVALIDATOR_NODE_PUB_KEY=$(cat ${CONFIG_PATH}/config/priv_validator_key.json | jq -r '.pub_key.value')\n
    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#4-submit-a-create-validator-proposal","title":"4. Submit a Create Validator Proposal","text":"

    Replace the values in the following JSON and save it as create_validator_proposal.json:

    {\n \"messages\": [\n  {\n   \"@type\": \"/cosmos.staking.v1beta1.MsgCreateValidator\",\n   \"description\": {\n    \"moniker\": \"${NODE_NAME}\",\n    \"identity\": \"\",\n    \"website\": \"\",\n    \"security_contact\": \"\",\n    \"details\": \"\"\n   },\n   \"commission\": {\n    \"rate\": \"0.070000000000000000\",\n    \"max_rate\": \"1.000000000000000000\",\n    \"max_change_rate\": \"0.010000000000000000\"\n   },\n   \"min_self_delegation\": \"1000000000000000000000\",\n   \"delegator_address\": \"${DELEGATOR_ADDR}\",\n   \"validator_address\": \"${VALIDATOR_ADDR}\",\n   \"pubkey\": {\n    \"@type\": \"/cosmos.crypto.ed25519.PubKey\",\n    \"key\": \"${VALIDATOR_NODE_PUB_KEY}\"\n   },\n   \"value\": {\n    \"denom\": \"BNB\",\n    \"amount\": \"1000000000000000000000\"\n   },\n   \"from\": \"0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2\",\n   \"relayer_address\": \"${RELAYER_ADDR}\",\n   \"challenger_address\": \"${CHALLENGER_ADDR}\",\n   \"bls_key\": \"${VALIDATOR_BLS}\", \n   \"bls_proof\": \"${VALIDATOR_BLS_PROOF}\"\n  }\n ],\n \"metadata\": \"\",\n \"title\": \"Create ${NODE_NAME} Validator\",\n \"summary\": \"create ${NODE_NAME} validator\",\n \"deposit\": \"1000000000000000000BNB\"\n}\n
    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#41-run-create-validator-command-to-submit-the-proposal-by-local-keys-ensure-the-delegator-account-has-enough-bnb-tokens","title":"4.1 Run create validator command to submit the proposal by local keys. Ensure the delegator account has enough BNB tokens.","text":"

    Info

    If you are utilizing the Cold Wallet or MPC wallet, please proceed to step #4.2.

    gnfd tx staking create-validator ./create_validator_proposal.json --keyring-backend test --chain-id \"greenfield_1017-1\" --from ${DELEGATOR_ADDR} --node \"https://greenfield-chain.bnbchain.org:443\" -b sync --gas \"200000000\" --fees \"1000000000000000000BNB\" --yes\n

    gnfd tx staking create-validator ./create_validator_proposal.json --keyring-backend test --chain-id \"greenfield_5600-1\" --from ${DELEGATOR_ADDR} --node \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\" -b sync --gas \"200000000\" --fees \"1000000000000000000BNB\" --yes\n

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#42-submit-the-proposal-by-gnfd-tx-sender-ensure-the-delegator-account-has-enough-bnb-tokens","title":"4.2 Submit the proposal by gnfd-tx-sender. Ensure the delegator account has enough BNB tokens.","text":"

    Run command to generate the transaction details.

    gnfd tx staking create-validator ./create_validator_proposal.json --from ${DELEGATOR_ADDR} --print-eip712-msg-type\n

    Submit the transaction using gnfd-tx-sender.

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#5-wait-for-the-voting-until-the-proposal-is-passed","title":"5. Wait for the voting until the Proposal is passed.","text":"

    After submitting the proposal successfully, you must wait for the voting to be completed and the proposal to be approved. It will last 7days on mainnet while 1 day on testnet. Once it has passed and is executed successfully, you can verify that the node has become a validator.

    Warning

    Please ensure that the validator node is running before it is selected. And the validator is responsible for running relayer and runing challenger, please ensure all these services are running as expected.

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#6-query-all-validators","title":"6. Query all validators","text":"MainnetTestnet
    gnfd query staking validators --node \"https://greenfield-chain.bnbchain.org:443\"\n
    gnfd query staking validators --node \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/","title":"Run Challenger - BNB Greenfield Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#prerequisites","title":"Prerequisites","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#recommended-hardware","title":"Recommended Hardware","text":"

    The following lists the recommended hardware requirements: - Hardware Requirements: Desktop or laptop hardware running recent versions of Mac OS X, or Linux. - CPU: 4 cores - RAM: 4 GB - Relational database: Mysql

    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#key-preparation","title":"Key Preparation","text":"

    These two keys refer to validator_challenger and validator_bls created in become-validator step 2.

    You can retrieve them with the following commands.

    gnfd keys export validator_challenger --unarmored-hex --unsafe --keyring-backend test\n\ngnfd keys export validator_bls --unarmored-hex --unsafe --keyring-backend test\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#prepare-binary","title":"Prepare Binary","text":"

    Get the greenfield-challenger app by running the following command in your terminal:

    git clone --branch \"$(curl -s https://api.github.com/repos/bnb-chain/greenfield-challenger/releases/latest  | jq -r '.tag_name')\" https://github.com/bnb-chain/greenfield-challenger.git\ncd greenfield-challenger\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#config","title":"Config","text":"

    Modify config/config.json. Or, you can create a new one and specify the config path by --config-path flag when start the challenger.

    Info

    Reference for a complete config file

    1. Set your private key and bls key (via file or aws secret).

       \"greenfield_config\": {\n   \"key_type\": \"local_private_key\" or \"aws_private_key\" depending on whether you are storing the keys on aws or locally in this json file\n   \"aws_region\": set this if you chose \"aws_private_key\"\n   \"aws_secret_name\": set this if you chose \"aws_private_key\"\n   \"aws_bls_secret_name\": set this if you chose \"aws_private_key\"\n   \"private_key\": set this if you chose \"local_private_key\"\n   \"bls_private_key\": set this if you chose \"local_private_key\" \n    ...\n }\n

      Note

      The term private_key refers to the private key of the validator_challenger account, while bls_private_key refers to the private key of the validator_bls account. To obtain these private keys, you can follow the instructions provided in the key preparation section.

    2. Set your RPC Address and Chain ID

      MainnetTestnet
      \"greenfield_config\": {\n    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\n    chainId = \"greenfield_1017-1\"\n}\n
      \"greenfield_config\": {\n    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n    chainId = \"greenfield_5600-1\"\n}\n
    3. Config your database settings.

      \"db_config\": {\n    \"dialect\": \"mysql\",\n    \"db_path\": \"your_db_path\"\n    \"key_type\": \"local_private_key\" or \"aws_private_key\" depending on whether you are storing the keys on aws or locally in this json file\n    \"aws_region\": set this if you chose \"aws_private_key\", else leave as \"\"\n    \"aws_secret_name\": set this if you chose \"aws_private_key\", else leave as \"\"\n    \"username\": set db username if you chose \"local_private_key\", else leave as \"\"\n    \"password\": set db password if you chose \"local_private_key\", else leave as \"\"\n    ...\n}\n
    4. Config your internal sp config (for metrics purpose).

      \"sp_config\": {\n    \"internal_sp_endpoints\": [] // list of internal sps' endpoints\n}\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#build","title":"Build","text":"

    Build binary:

    make build\n

    Build docker image:

    make build_docker\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#run","title":"Run","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#run-mysql-in-dockerthis-can-be-skipped-if-you-are-using-sqlite","title":"Run MySQL in Docker(this can be skipped if you are using sqlite)","text":"
    docker run --name gnfd-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#create-db-schema","title":"Create DB Schema","text":"

    Create schema in MySQL client:

    CREATE SCHEMA IF NOT EXISTS `challenger` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#start-challenger","title":"Start Challenger","text":"
    ./build/greenfield-challenger --config-type [local or aws] --config-path config_file_path  --aws-region [aws region or omit] --aws-secret-key [aws secret key for config or omit]\n

    Example:

    ./build/greenfield-challenger --config-type local --config-path config/config.json\n

    Run docker:

    docker run -it -v /your/data/path:/greenfield-challenger -e CONFIG_TYPE=\"local\" -e CONFIG_FILE_PATH=/your/config/file/path/in/container -d greenfield-challenger\n

    Or you can deploy the greenfield challenger application using Helm Chart V3. Please refer to challenger-readme.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/","title":"Run Node - BNB Greenfield Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-node/#run-node","title":"Run Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-node/#minimum-system-requirements","title":"Minimum System Requirements","text":"

    The hardware must meet certain requirements to run a Full Node.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#setting-up-a-new-node","title":"Setting Up a New Node","text":"

    Info

    Please check the greenfield repo for information, including the correct version of the binaries to use and details about the config file

    1. You need to choose a home folder $NODE_HOME (i.e. ~/.gnfd) for Greenfield Chain. You can setup this by:

    mkdir ~/.gnfd\nmkdir ~/.gnfd/config\n
    2. Download app.toml, config.toml and genesis.json from https://github.com/bnb-chain/greenfield/releases and copy them into $NODE_HOME/config mainnettestnet
    wget  $(curl -s https://api.github.com/repos/bnb-chain/greenfield/releases/latest |grep browser_ |grep mainnet_config |cut -d\\\" -f4)\nunzip mainnet_config.zip\ncp mainnet_config/*  ~/.gnfd/config/\n
    wget  $(curl -s https://api.github.com/repos/bnb-chain/greenfield/releases/latest |grep browser_ |grep testnet_config |cut -d\\\" -f4)\nunzip testnet_config.zip\ncp testnet_config/*  ~/.gnfd/config/\n

    You can edit this moniker later, in the $NODE_HOME/config/config.toml file:

    # A custom human readable name for this node\nmoniker = \"<your_custom_moniker>\"\n

    Note

    Monikers can contain only ASCII characters. Using Unicode characters will render your node unreachable.

    Now your Full Node has been initialized.

    1. Start your Full Node.
    gnfd start\n

    Note

    Alternatively, if you choose a different $NODE_HOME location and you are not using the suggested default ~/.gnfd, you may start the full node by using below script, where $NODE_HOME is your selected directory.

    Example: If you set /usr/local/gnfd as your home directory. Run the Full Node with below command.

    gnfd start --home /usr/local/gnfd\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#additional-configuration","title":"Additional Configuration","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-node/#get-extra-information-from-your-fullnode","title":"Get Extra Information From Your Fullnode","text":"

    If you have a Full Node running, then you can publish extra messages to local files.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#monitor-syncing-process","title":"Monitor Syncing Process","text":"

    You can verify if state sync is done by curl localhost:26657/status several times and see whether latest_block_height is increasing in response.

    \"sync_info\": {\n  ...\n  \"latest_block_height\": \"280072\",\n  \"latest_block_time\": \"2023-04-07T01:58:13.572249854Z\",\n  ...\n}\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#prometheus-metrics","title":"Prometheus Metrics","text":"

    Prometheus is enabled on port 26660 by default, and the endpoint is /metrics.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#tools","title":"Tools","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/","title":"Run Relayer - BNB Greenfield Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#run-relayer","title":"Run Relayer","text":"

    This tutorial is for running relayers for Greenfield to BSC and opBNB. Please note that they are using the same binary, but two individual processes which require different databases connected. Most configs for these two relayers are the same, with a few differences which will be illustrated below.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#prerequisites","title":"Prerequisites","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#recommended-hardware","title":"Recommended Hardware","text":"

    The following lists the recommended hardware requirements: - Hardware Requirements: Desktop or laptop hardware running recent versions of Mac OS X, or Linux. - CPU: 4 cores - RAM: 4 GB - Relational database: Mysql

    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#key-preparation","title":"Key Preparation","text":"

    These two keys refer to validator_relayer and validator_bls created in become-validator step 2.

    You can retrieve them with the following commands.

    gnfd keys export validator_relayer --unarmored-hex --unsafe --keyring-backend test\n\ngnfd keys export validator_bls --unarmored-hex --unsafe --keyring-backend test\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#prepare-binary","title":"Prepare binary","text":"

    Get the greenfield-relayer app by running the following command in your terminal:

    git clone --branch \"$(curl -s https://api.github.com/repos/bnb-chain/greenfield-relayer/releases/latest  | jq -r '.tag_name')\" https://github.com/bnb-chain/greenfield-relayer.git\ncd greenfield-relayer\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#config","title":"Config","text":"

    Modify config/config.json. Or, you can create a new one and specify the config path by --config-path flag when start the relayer.

    Info

    For Testnet config, refer to Testnet configure. You can use it as a template for your Mainnet config by adapting a few changes as illustrated below.

    1. Set relayer private key and bls private key import method (via file or aws secret) and keys, the block monitoring start heights.

      \"greenfield_config\": {\n  \"key_type\": \"local_private_key\", // or \"aws_private_key\" if you are using aws secret manager.\n   ...\n  \"aws_bls_secret_name\": \"\",\n  \"private_key\": \"your_private_key\", // this is the relayer private key for relaying transaction.\n  \"bls_private_key\": \"your_private_key\", // this is the bls key for signing crosschain package.\n  \"rpc_addrs\": [\n    \"https://greenfield-chain.bnbchain.org:443\"\n   ]\n  \"chain_id\": 1017,\n   ...\n  \"start_height\": 1,  // please change to the current block height of Greenfield network.\n  \"chain_id_string\": \"greenfield_1017-1\"\n}, \n\"bsc_config\": {\n  \"key_type\": \"local_private_key\",  // or \"aws_private_key\" if you are using aws secret manager.\n  ...\n  \"rpc_addrs\": [\n     \"BSC_RPC\"\n  ],\n  \"private_key\": \"your_private_key\", // same as the above one in greenfield_congfig.\n  \"gas_limit\": 20000000,\n  ...\n  \"start_height\": 0,   // please change to the current block height of BSC network.\n  \"chain_id\": 56  // 56 is BSC Mainnet chain id.\n}\n
      For setting up the relayer that crosschain to opBNB, modify the bsc_config as below.
      \"bsc_config\": {\n     \"op_bnb\": true, // this specifies that conifg is for opBNB crosschain.\n     \"key_type\": \"local_private_key\",  // or \"aws_private_key\" if you are using aws secret manager.\n     ...\n     \"rpc_addrs\": [\n        \"opBNB_RPC\"\n     ],\n     \"private_key\": \"your_private_key\", // same as the above one in greenfield_congfig.\n     \"gas_limit\": 20000000,\n     ...\n     \"start_height\": 0,   // please change to the current block height of opBNB network.\n     \"chain_id\": 204 // opBNB mainnet chain id\n   }\n
      Note: Refer to Greenfield Endpoints for Greenfield RPC address, BSC Endpoints for BSC RPC address, and use the appropriate ones based on your location, opBNB Endpoints for opBNB RPC address, and use the appropriate ones based on your location. You might encounter Rate limit issue for using official BSC/opBNB endpoints, we would highly recommend using 3rd Party RPCs, like the NodeReal MegaNode
    2. Config crossChain, greenfield light client and relayer hub smart contracts addresses, others can keep the default value, refer to this contract-list to get addresses for Mainnet/Testnet.

      BSC-MainnetBSC-TestnetopBNB-MainnetopBNB-Testnet
      \"relay_config\": {\n    ... \n    \"cross_chain_contract_addr\": \"0x77e719b714be09F70D484AB81F70D02B0E182f7d\",\n    \"greenfield_light_client_contract_addr\": \"0x433bB48Bd86c089375e53b2E2873A9C4bC0e986B\",\n    \"relayer_hub_contract_addr\": \"0x31C477F05CE58bB81A9FB4b8c00560f1cBe185d1\"\n}\n
      \"relay_config\": {\n  ... \n  \"cross_chain_contract_addr\": \"0xa5B2c9194131A4E0BFaCbF9E5D6722c873159cb7\",\n  \"greenfield_light_client_contract_addr\": \"0xa9249cefF9cBc9BAC0D9167b79123b6C7413F50a\",\n  \"relayer_hub_contract_addr\": \"0x91cA83d95c8454277d1C297F78082B589e6E4Ea3\"\n}\n
      \"relay_config\": {\n  ... \n  \"cross_chain_contract_addr\": \"0x7E376AEFAF05E20e3eB5Ee5c08fE1B9832b175cE\",\n  \"greenfield_light_client_contract_addr\": \"0xf51ba131716776685A805E8E4Ecc95be2f923B93\",\n  \"relayer_hub_contract_addr\": \"0xEd873b460C53D22f0FF3fc511854d9b8b16C4aE2\"\n}\n
      \"relay_config\": {\n  ... \n  \"cross_chain_contract_addr\": \"0xF0Bcf6E4F72bCB33b944275dd5c9d4540a259eB9\",\n  \"greenfield_light_client_contract_addr\": \"0xc50791892F6528E42A58DD07869726079C71F3f2\",\n  \"relayer_hub_contract_addr\": \"0x59ACcF658CC4589C3C41720fd48e869B97A748a1\"\n}\n
    3. Config the database settings.

          \"db_config\": {\n    \"dialect\": \"mysql\",\n    \"key_type\": \"local_private_key\",\n    \"aws_region\": \"\",\n    \"aws_secret_name\": \"\",\n    \"password\": \"${pass}\",\n    \"username\": \"${user}\",\n    \"url\": \"tcp(${host})/greenfield-relayer?charset=utf8&parseTime=True&loc=Local\",\n    \"max_idle_conns\": 10,\n    \"max_open_conns\": 100\n    }\n
      Note: Please replace ${pass}, ${user}, ${host} with your Mysql instance credential and host. And use a distinct database other than greenfield-relayer, e.g. greenfield-op-relayer when running the Greenfield Relayer for crosschain to opBNB on the same DB instance.
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#build","title":"Build","text":"

    Build the binary:

    make build\n

    Or Build docker image:

    make build_docker\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#run","title":"Run","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#create-db-schema","title":"Create DB Schema","text":"

    Make sure the database instance is running.

    Create schema by MySQL client:

    CREATE SCHEMA IF NOT EXISTS `greenfield-relayer` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#start-relayer","title":"Start Relayer","text":"
    ./build/greenfield-relayer --config-type [local or aws] --config-path config_file_path  --aws-region [aws region or omit] --aws-secret-key [aws secret key for config or omit]\n

    Example:

    ./build/greenfield-relayer --config-type local --config-path config/config.json\n

    Run docker:

    docker run -it -v /your/data/path:/greenfield-relayer -e CONFIG_TYPE=\"local\" -e CONFIG_FILE_PATH=/your/config/file/path/in/container -d greenfield-relayer\n

    Or you can deploy the greenfield relayer application using Helm Chart V3. Please refer to relayer-readme.

    "},{"location":"bnb-greenfield/getting-started/dcellar/","title":"Dcellar - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/dcellar/#use-greenfield-in-dcellar","title":"Use Greenfield in Dcellar","text":"

    DCellar is a powerful tool that allows users to initiate their decentralized data management journey on the Greenfield platform. It is developed based on Greenfield by Nodereal. With DCellar, users can store and share their data, as well as manage their account assets.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#login","title":"Login","text":"

    Simply open the web browser and navigate to dcellar.io. You will be greeted with a Welcome Screen that provides a simple and user-friendly interface.

    To get started, click on the Get Started button, and your wallet extension will automatically be activated. This will log you in with your current wallet account, allowing you to access all the features and functions of DCellar. With this easy and straightforward process, even first-time users can quickly get started with decentralized data management on the Greenfield platform.

    For first time users, you will need to add Greenfield Network to your Wallet, and you will be asked to switch your network to Greenfield Network to start following operations.

    You can also add Greenfield Network to your wallet manually, you can find it at bnbchainlist

    For returning users, you will stay logged in for a default time period. During the default time period, you will stay logged in when you come back. After that, you will need to login with wallet again. If you want to switch to your other wallet accounts, you can try Disconnect first, and then login again with another account.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#transfer-in","title":"Transfer In","text":"

    Before you can begin storing your objects with DCellar, you\u2019ll need to transfer several amounts of BNB tokens from your BSC account to your Greenfield account. These two accounts share the same account address, making the transfer process straightforward and hassle-free.

    By transferring BNB tokens to your Greenfield account, you\u2019ll be able to cover the transaction fees associated with storing and managing your objects on the Greenfield platform. Once you\u2019ve completed this step, you\u2019ll be ready to start using DCellar and taking advantage of all its powerful features and benefits.

    Once you\u2019ve logged in to DCellar, you can access the Transfer In tab by navigating to the Wallet Page. Before you begin the transfer process, it\u2019s important to ensure that you\u2019re currently using the BSC .

    If you\u2019re using the Greenfield Network, the Transfer In page will be displayed differently. To avoid any confusion, make sure that you\u2019re on the correct network before proceeding with the transfer process. By following these simple steps, you can quickly and easily transfer BNB tokens to your Greenfield account and start using DCellar to manage your decentralized data.

    Click Switch to BNB Smart Chain, your wallet will be notified, informing you to switch network, by clicking Switch Network button on wallet pop-up, you will be able to switch to BSC . If you haven\u2019t added a BSC network yet, wallet will ask you to add a network first, then switch to this network.

    You will be able to Transfer a certain amount of BNB token from your BSC account to your Greenfield account which shares the same address. Transfer In will cost you two kinds of fees, all charged by BNB token:

    Input the amount you want to Transfer In, Click Transfer In, your transaction will be sent. You can view your transaction details in explorer.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#create-bucket","title":"Create Bucket","text":"

    Before you start using DCellar to manage your objects, you should make sure you are currently under Greenfield Network. If you are under another network, you will be asked to Switch to BNB Greenfield first.

    A bucket is a logical container for storing objects in Greenfield. Once a bucket has been created, you can upload your objects to a certain bucket. After Login, you can see the New Bucket button at your bucket list page.

    After clicking New Bucket, a pop-up will show and you will be asked to enter a bucket name. Each bucket has a unique name that is assigned by the user when the bucket is created. Please follow the naming rules, carefully select your bucket name:

    By selecting a primary storage provider, you will decide the main storage service provider for all the datas within this particular bucket.

    By selecting a payment account, all storage service fee will be charged from this selected payment account, while gas fee will charged from your current login account, which is also your owner account. If your balance is insufficient, you will be informed to Transfer In first. For more information about Owner Account and Payment Account, Please Go to Greenfield Doc- Greenfield Documentation.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#upload-object","title":"Upload Object","text":"

    Choose one bucket on your bucket list page, you can see the objects within this bucket. Click Upload , you will be able to choose a locally stored object.

    When you are uploading a object, gas fee will be charged from your current login account, which is also your owner account. Besides, once your object is uploaded successfully, you will be charging a storage fee under a certain flow rate. Therefore, when you are uploading a object, you need to make sure that your owner account has enough balance to cover the storage fee for the following six months. which will be shown as Prepaid fee as follows.

    Info

    Please notice that the prelocked fee is not charged at the beginning, it is still in your owner account. But you are not allowed to use it for other purposes because it\u2019s \u201clocked\u201d.

    Besides prepaid fee, each operation will bring settlement, which might generate settlement fee. Learn more about Greenfield Settlement.

    Moreover, you can select the permission property of the selected object, DCellar will set your object as private by default.

    After you successfully upload your data, Greenfield will start to charge storage fee from your locked fee in your account. You can view your total \u201clocked fee\u201d at your account page.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#create-folder","title":"Create Folder","text":"

    You can create folders to better organize your objects. carefully choose your folder name, avoid \u201c/\u201d in your folder name.

    Create folder will cost you some gas fee. Also, every operation will bring settlement, so there might be settlement fee. Settlement fee will be charged from the payment account, while gas fee will be charged from owner account.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#download-object","title":"Download Object","text":"

    When you are downloading a object, gas fee will not be charged. But it will cost your some Download bandwidth.

    Info

    Each download operation will consume Download Quota, which is related to object size. In the current testing phase, each bucket will be given 1G\u2019s free quota.

    You can check your bucket\u2019s remaining quota at Bucket Detail page

    When your remaining quota is smaller than the required quota for a certain object you are downloading, your download will fail, you will be reminded to buy more quota.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#manage-quota","title":"Manage Quota","text":"

    You can buy quota by month. Choose the amount you want to buy. Please notice that when you download objects, the system will automatically use the free quota first, which will not expire during your usage period. After your free quota is used out, system will start to use the download quota you bought. If your purchased quota is not use out before the end of the month, your monthly quota will expire.

    When you buy monthly quota, it means you agree to buy monthly quota in the following month, if you want to stop buying monthly quota, you need to update your monthly quota, set monthly quota amount to 0.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#delete-object","title":"Delete Object","text":"

    When you are deleting a object, gas fee will be charged from your owner account. If your balance is insufficient, you will be informed to Transfer In first. Besides, when your object is deleted, your flow rate will be recalculated, and part of your prepaid fee will be refund. So you can see your \u201cPrepaid fee refund\u201d as follows when deleting a object.

    Info

    Please notice if your data has been stored less than 6 months, your prepaid fee will not be refund.

    Also, every operation will bring settlement, so there might be settlement fee. Settlement fee will be charged from the payment account.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#delete-bucket","title":"Delete Bucket","text":"

    You can delete the bucket created by you. Please notice you are only allowed to delete an empty bucket, which means you need to delete all your objects in the bucket before you delete the bucket. When you are deleting a bucket, gas fee will be charged from your current login account, which is also your owner account.

    If you have bought monthly quota for the bucket, when you delete bucket, system will refund your prepaid fee for monthly quota no matter when you decide to delete your bucket. This is a bit different with prepaid fee refund when deleting objects, which has 6 6-month min lock time.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#monitor-usage","title":"Monitor Usage","text":"

    With DCellar, you can Monitor your usage through your Dashboard.

    Besides, you can also view your expenses via account and account detail.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#send","title":"Send","text":"

    With the DCellar, you can easily send BNB tokens from your Greenfield owner account to another Greenfield owner account. However, before you initiate any token transfers, it\u2019s important to ensure that you\u2019re currently using the correct network. If you\u2019re using the BSC instead of the Greenfield , the Send page will be displayed differently. To avoid any mistakes or confusion, always double-check that you\u2019re on the correct network before sending tokens to another user. By taking this simple precaution, you can ensure that your token transfers are executed smoothly and efficiently, enabling you to manage your decentralized data with ease using DCellar.

    To switch to the BNB Greenfield network, simply click on the \u201cSwitch to BNB Greenfield\u201d button within DCellar. This will automatically activate your wallet extension, which will display a pop-up informing you that you need to switch networks. To proceed, simply click on the \u201cSwitch Network\u201d button within the wallet pop-up. This will allow you to switch to the Greenfield .

    Info

    Before Sending, please make sure the address you enter is a valid Greenfield account address.

    Enter the receiver\u2019s address and the amount you want the send, click Send, your transaction will be sent to Greenfield , and you will need to pay the gas fee on Greenfield .

    "},{"location":"bnb-greenfield/getting-started/dcellar/#transfer-out","title":"Transfer Out","text":"

    With DCellar, you can transfer out BNB token from your Greenfield account to your BSC account which shares the same address. Before you Transfer Out, you should make sure you are currently under Greenfield . If you are under BSC , your Transfer Out page will be shown as follows:

    To switch to the BNB Greenfield network, simply click on the Switch to BNB Greenfield button within DCellar. This will automatically activate your wallet extension, which will display a pop-up informing you that you need to switch networks. To proceed, simply click on the Switch Network button within the wallet pop-up. This will allow you to switch to the Greenfield , where you can begin managing your decentralized data with DCellar. By following these simple steps, you can quickly and easily switch networks and access all the powerful features and functions of DCellar on the Greenfield platform.

    Transfer Out will cost you two kinds of fees, all charged by BNB token:

    Input the amount you want to Transfer Out, Click Transfer Out, your transaction will be sent. You can view your transaction details in GreenfieldScan.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/","title":"General FAQ - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/general-faqs/#why-cant-i-send-bnb-tokens-on-bnb-greenfield-using-my-wallet","title":"Why can\u2019t I send BNB tokens on BNB Greenfield using my wallet?","text":"

    Wallet does not support transfers on BNB Greenfield because BNB Greenfield uses a different transaction format than other EVM chains. You may encounter the following error when you transfer your token with your wallet. To send BNB tokens on BNB Greenfield, you need to use dCellar Transfer function.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#how-to-understand-the-amount-field-in-the-signature-message-when-using-bnb-greenfield","title":"How to understand the amount field in the signature message when using BNB Greenfield?","text":"

    When users perform actions on the BNB Greenfield, such as creating buckets or uploading files, they need to sign a message that contains the amount of BNB they are spending. However, this amount is not in BNB units, but in WEI units, which are much smaller. One WEI is equal to 10^-18 BNB. Therefore, the amount field in the signature message may look very large, but it is actually a very small fraction of a BNB.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#does-greenfield-have-a-token-how-can-i-get-it","title":"Does Greenfield have a token? How can I get it?","text":"

    BNB remains the main utility token on Greenfield, no other token on Greenfield. You can acquire BNB in multiple ways:

    1. Buy BNB if you never own it.
    2. Cross-chain transfer BNB from BSC network to Greenfield using DCellar if you already own any BNB. You can read the detailed steps here. The cross-chain token transfer is really fast, you are supposed to receive your BNB within a minute.
    3. Receive BNB from other Greenfield users with internal transactions
    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-the-utility-of-bnb-on-greenfield","title":"What is the utility of BNB on Greenfield?","text":"

    BNB is used as a staking token, gas token, storage service fee token, and governance token. Refer to token economics for more details.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#does-greenfield-support-smart-contract","title":"Does Greenfield support smart contract?","text":"

    The Greenfield blockchain does not support smart contracts, but the native cross-chain between BSC and Greenfield brings programmability to the ecosystem. More tech details are explained here, you can start integrating smart contracts with Greenfield following the tutorial.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-consensus-algorithm-does-greenfield-run-on","title":"What consensus algorithm does Greenfield run on?","text":"

    Tendermint is the consensus engine that powers Greenfield BPoS.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#is-the-file-permanently-stored-in-greenfield","title":"Is the file permanently stored in Greenfield?","text":"

    No. Currently, Greenfield charges storage fees in a stream manner, so if a user\u2019s account balance is insufficient and in arrears, it is possible that their data may be lost and cannot be recovered.

    Greenfield may support permanent storage in the future.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#can-i-update-the-files-after-it-is-uploaded","title":"Can I update the files after it is uploaded?","text":"

    The update is not yet supported, but it can be accomplished through deletion and upload.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#can-i-enjoy-lower-price-for-the-data-i-previously-stored-if-the-storage-price-goes-down","title":"Can I enjoy lower price for the data I previously stored if the storage price goes down?","text":"

    Sure, but it requires any transaction that modifies the payment flow, such as uploading or deleting files, to trigger it.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#will-i-also-have-to-pay-more-for-the-data-i-have-previously-stored-if-the-storage-price-goes-up","title":"Will I also have to pay more for the data I have previously stored if the storage price goes up?","text":"

    In theory, yes. However, Greenfield will strictly limit the frequency and magnitude of price adjustments by storage providers to minimize the impact on users.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#if-the-storage-provider-loses-my-data-or-refuses-to-provide-service-what-can-i-do","title":"If the storage provider loses my data or refuses to provide service, what can I do?","text":"

    This situation is usually unlikely to happen because Greenfield uses redundant error-correction coding to keep your data safe across multiple storage providers.

    If such a scenario occurs, you can initiate a data availability challenge, and validators will verify the integrity, availability, and service quality of your data while penalizing the corresponding storage provider.

    You can continue to receive rewards until the storage provider fully recovers your data or provides the service.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#how-can-i-make-my-valuable-data-circulate","title":"How can I make my valuable data circulate?","text":"

    You can mirror your data and access permissions to the BNB Smart Chain network, and trade your data through various DApps and data trading platforms.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#how-long-can-the-data-uploaded-to-the-testnet-be-saved","title":"How long can the data uploaded to the testnet be saved?","text":"

    Testnet is used for testing, so it won\u2019t keep user\u2019s data for a long time. It is expected to be dropped after 7 days.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-to-do-if-you-are-unable-to-upgrade-greenfield-in-time","title":"What to do if you are unable to upgrade Greenfield in time?","text":"

    Since this is a hardfork, your gnfd binary cannot continue running if it\u2019s not upgraded in time. Add the following filed in app.toml:

    # chain-id for op bnb destination chain \n`dest-op-chain-id = 204`\n
    Stop the binary, then execute the rollback command: gnfd rollback --hard Finally, restart your binary."},{"location":"bnb-greenfield/getting-started/general-faqs/#how-much-does-it-cost-to-store-files-in-greenfield","title":"How much does it cost to store files in Greenfield?","text":"

    If you\u2019re interested in knowing the real-time pricing for storage and querying on Greenfield, we invite you to the Price Calculator.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#how-is-my-billing-calculated","title":"How is my billing calculated?","text":"

    In Greenfield, bsides transaction fee, users are required to pay two kinds of storage service fees: storage fee and download quota fee. These storage service fees are charged by Storage Providers (SPs) in a stream payment. Users need to lock some BNB when they start using the service.

    Storage Fee = sum(ChargedSize) * (PrimaryStorePrice + SecondaryStorePrice*SecondarySPNumber) * (1+Validator Tax Rate) * ReserveTime\n
    Download Quota Fee = ChargedReadQuota * ReadPrice * (1 + Validator Tax Rate) * ReserveTime\n

    Currently, ReserveTime is 180 days and Validator Tax Rate is 1%

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-charged-size","title":"What is Charged Size?","text":"

    The ChargeSize is calculated from the object\u2019s payload size, if the payload size is less than 128k then ChargeSize is 128k, otherwise ChargeSize is equal to payload size.

    If Data Size < 128K, ChargedSize = 128K; else, ChargedSize = Data Size

    If object is an empty folder, ChargedSize = 128K

    You can query the value from this API

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-primarysecondary-store-price","title":"What is Primary/Secondary Store Price?","text":"

    Every SP can set their own suggested store price and read price via on-chain transactions. At the first block of each month, the median all SPs\u2019 store prices will be calculated as the Primary SP Store Price, the Secondary SP Store Price will be calculated as SecondaryPriceRatio (e.g. 12%, which can be governed) multiply the Primary SP Store Price , and the median of all SPs\u2019 read prices will be calculated as the Primary SP Read Price. To learn more about it, please refer to this

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-validator-tax-rate","title":"What is Validator Tax Rate?","text":"

    For each data related operation on Greenfield, validators can get some rewards for protecting the security and integrity of data (i.e. challenge). Through charging validator tax, part of user\u2019s cost will go to validator tax pool, and then become validators\u2019 rewards.

    You can query the value from this API

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-read-price","title":"What is Read Price?","text":"

    A storage provider can update its free read quote and monthly gree read quota, suggested primary store price and read price. All SPs\u2019 suggested primary store and read prices will be used to generate the global primary/secondary store price and read price.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-reserve-time","title":"What is Reserve Time?","text":"

    The storage fee will be charged on Greenfield in a steam payment style. The fees are paid on Greenfield in the style of \u201cStream\u201d from users to receiver accounts at a constant rate. By reseveing some balance, users do not need to payment the fee in a very high frequency. Currently, the reserve time is 6 months and it can be governed.

    You can query the value from this API

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#whats-best-practice-to-store-small-files-in-greenfield","title":"What\u2019s best practice to store small files in Greenfield?","text":"

    If a single transaction only store a small size file to the Greenfield Network, it is like separate packages being sent through the mail \u2013 even though they were all going to the same destination. It\u2019s recommended to take all of the files to reach the Charged Size and put them together to get sent as one transaction to the network.

    "},{"location":"bnb-greenfield/getting-started/get-test-bnb/","title":"Faucet - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/get-test-bnb/#faucet","title":"Faucet","text":"

    You can claim the test tBNB tokens on BSC Testnet by the faucet, and bridge it to Greenfield Testnet.

    "},{"location":"bnb-greenfield/getting-started/get-test-bnb/#claim-tbnb-from-bsc-faucet","title":"Claim tBNB from BSC Faucet","text":"
    1. Vist BSC faucet.

    2. Switch to the BSC Testnet in your wallet and check your balance.

    "},{"location":"bnb-greenfield/getting-started/get-test-bnb/#bridge-to-greenfield","title":"Bridge to Greenfield","text":"

    You can use BNB Greenfield Bridge or DCellar Testnet to transfer BNB from BSC to Greenfield and vice versa. You can follow How to Transfer In to bridge tBNBs from BSC Testnet to Greenfield Testnet, and How to Transfer Out to bridge tBNBs from Greenfield Testnet to BSC Testnet.

    "},{"location":"bnb-greenfield/getting-started/greenfield-command/","title":"Greenfield Command - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/greenfield-command/#greenfield-command","title":"Greenfield Command","text":"

    Greenfield Command is a powerful command line for you to manage your resources on Greenfield and interact with Greenfield.

    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#command-tool-guide","title":"Command Tool Guide","text":"

    This command tool supports basic storage functions, including creating buckets, uploading and downloading files, and deleting resources. It also supports related operations such as groups, policies, banks, accounts and so on. To make the command display clearer, commands of different categories are implemented as subcommands of different categories. You can use \u201cgnfd-cmd -h\u201d to view the supported command categories.

    The command tool supports the \u201c\u2013home\u201d option to specify the path of the config file and the keystore, the default path is a directory called \u201c.gnfd-cmd\u201d under the home directory of the system. When running commands that interact with the greenfield, if there is no config/config.toml file under the path and the commands runs without \u201c\u2013config\u201d flag, the tool will generate the config/config.toml file automatically which is consistent with the testnet configuration under the path.

    Below is examples of the config file of Testnet and Mainnet. The rpcAddr and chainId should be consistent with the Greenfield network. For Greenfield Mainnet, you can refer to Greenfield Mainnet RPC Endpoints. The rpcAddr indicates the Tendermint RPC address with the port info.

    The command has the ability to intelligently select the correct storage provider to respond to the request. The user only needs to set the storage provider operator-address if they want to create a bucket on a specific SP. For example, the user can run \u201cgnfd-cmd storage put test gnfd://bucket1/object1\u201d to upload a file to bucket1 and then run \u201cgnfd-cmd storage put test gnfd://bucket2/object\u201d to upload a file to bucket2, which is stored on another SP without changing the config.

    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#basic-operations","title":"Basic Operations","text":""},{"location":"bnb-greenfield/getting-started/greenfield-command/#account-operations","title":"Account Operations","text":"

    Before using the rich features of the command tool, you need to init account info and generate keystore by \u201caccount import\u201d or \u201caccount new\u201d command . All the other commands need to load the keystore content before running.

    The \u201cimport\u201d command imports account info from private key file and generate a keystore by following four steps:

    1. Export your private key from MetaMask and write it into a local file as plaintext (You can select \u201cAccount Details\u201d from the dropdown menu of MetaMask. Click on the \u201cExport Private Key\u201d button at the bottom of the page.)
    2. Generate a keystore by the \u201caccount import [keyfile]\u201d command. Users need set the private key file path, which is created by step 1.
      // import key and generate a keystore file \ngnfd-cmd account import key.txt\n
    3. The terminal will prompt user to enter the password information. Users can also specify the password file path by using the \u201c\u2013passwordfile\u201d. Users are responsible for managing their password information.

    The keystore will be generated in the path \u201ckeystore/keyfile\u201d under the home directory of the system or the directory set by \u201c-home\u201d. And it is also the path to load keystore when running other commands.

    1. Delete the private key file which is created in step 1. It is not needed after the keystore has been generated.

    If the user has no private key to import, he can use \u201caccount new\u201d create a new greenfield account and the keystore. After creating the account, the user needs to transfer token to the address of this account before using other commands to send transactions or use storage-related functions.

    // new account and generate keystore key.json\ngnfd-cmd account account new\n

    To obtain the account and keystore info, users can use \u201caccount export\u201d to print the private key info and \u201caccount ls\u201d to display the accounts information.

    // list the account info and keystore path\ngnfd-cmd account ls\n\n// display the encrypted keystore or the private key \ngnfd-cmd account export --unarmoredHex --unsafe\n

    Users can create multiple accounts using the \u201caccount import\u201d or \u201caccount new\u201d command. You can use the \u201cset-default\u201d command to specify which account to use for running other commands by default. When executing commands using the default account, there is no need to specify the keystore.

    // set the default account.\ngnfd-cmd account set-default [address]\n
    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#sp-operations","title":"SP Operations","text":"

    Before making a bucket and uploading files, we need to select a storage provider to store the files in the bucket. By executing the following command, we can obtain a list of storage providers on Greenfield.

    $ gnfd-cmd sp ls\nname     operator address                           endpoint                               status\nbnbchain 0x231099e40E1f98879C4126ef35D82FF006F24fF2 https://greenfield-sp.bnbchain.org:443 IN_SERVICE\ndefibit  0x05b1d420DcAd3aB51EDDE809D90E6e47B8dC9880 https://greenfield-sp.defibit.io:443   IN_SERVICE\nninicoin 0x2901FDdEF924f077Ec6811A4a6a1CB0F13858e8f https://greenfield-sp.ninicoin.io:443  IN_SERVICE\nnariox   0x88051F12AEaEC7d50058Fc20b275b388e15e2580 https://greenfield-sp.nariox.org:443   IN_SERVICE\nlumibot  0x3131865C8B61Bcb045ed756FBe50862fc23aB873 https://greenfield-sp.lumibot.org:443  IN_SERVICE\nvoltbot  0x6651ED78A4058d8A93CA4979b7AD516D1C9010ac https://greenfield-sp.voltbot.io:443   IN_SERVICE\nnodereal 0x03c0799AD70d19e723359E036a83E8f44f4B8Ba7 https://greenfield-sp.nodereal.io:443  IN_SERVICE\n
    And the Users can obtain detailed information about a certain SP by \u201csp head\u201d and \u201csp get-price\u201d commands. Here is an example of obtaining information about an SP with endpoint https://greenfield-sp.nodereal.io:443.
    // get storage provider info\n$ gnfd-cmd sp head  https://greenfield-sp.nodereal.io:443\n\n// get quota and storage price info of storage provider:\n$ gnfd-cmd sp get-price https://greenfield-sp.nodereal.io:443\nget bucket read quota price: 0.1469890427  wei/byte\nget bucket storage price: 0.02183945725  wei/byte\nget bucket free quota: 1073741824\n

    You can take note of the operator-address information for the storage provider to which is intended to be uploaded. This parameter will be required for making the bucket in the next step.

    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#bucket-operation","title":"Bucket Operation","text":"

    You can run \u201c./gnfd-cmd bucket -h \u201d to get help of the bucket operations.

    The below command can be used to create a new bucket called testbucket:

    gnfd-cmd bucket create gnfd://testbucket\n

    The command supports \u201c-primarySP\u201d flag to select the storage provider on which you want to create a bucket. The content of the flag should be the operator address of the storage provider. If this value is not set, the first SP in the storage provider list will be selected as the upload target by default.

    The user can update the bucket meta by the \u201cbucket update\u201d command. It supports updating bucket visibility, charged quota, or payment address.

    // update bucket charged quota \ngnfd-cmd bucket update --chargedQuota 50000 gnfd://testbucket\n// update bucket visibility\ngnfd-cmd bucket update --visibility=public-read gnfd://testbucket\n

    The user can use list the buckets which belong to him with \u201cbucket ls\u201d commands.

     gnfd-cmd bucket ls\n
    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#uploaddownload-files","title":"Upload/Download Files","text":"

    (1) put Object

    The user can upload the local file to the bucket by the \u201cobject put\u201d command. The following command example uploads an object named \u2018testobject\u2019 to the \u2018testbucket\u2019 bucket. The file payload for the upload is read from the local file indicated by \u2018file-path\u2019.

    gnfd-cmd object put --contentType \"text/xml\" file-path gnfd://testbucket/testobject\n

    If the object name has not been set, the command will use the file name as object name. After the command is executed, it will send createObject txn to the chain and uploads the payload of the object to the storage provider. The command will return after object completes sealing. Users can also choose to interrupt the sealing process, which does not affect the final completion of the object. During the upload process, the terminal will print the upload progress and upload speed.

    (2) download object

    The user can download the object into the local file by the \u201cobject get\u201d command. The following command example downloads \u2018testobject\u2019 from \u2018testbucket\u2019 to the local \u2018file-path\u2019 and prints the length of the downloaded file. The filepath can be a specific file path, a directory path, or not set at all. If the file-path is not set, the command will download the content to a file with the same name as the object name in the current directory.

    gnfd-cmd object get gnfd://testbucket/testobject file-path\n

    After the command is executed, it will send a download request to the storage provider and download the object. The terminal will print the download progress and speed.

    (3) list object and delete object

    The user can use list the objects of the specific bucket with \u201cobject ls\u201d command.

     gnfd-cmd object ls gnfd://testbucket\n
    The user can delete the object with \u201cobject delete\u201d command.
     gnfd-cmd object delete gnfd://testbucket/testobject \n
    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#group-operation","title":"Group Operation","text":"

    Users can run \u201c./gnfd-cmd group -h \u201d to get help of group operations.

    The user can create a new group by the \u201cgroup create\u201d command. Note that this command can set the initialized group member through the \u2013initMembers parameter. After the command executes successfully, the group ID and transaction hash information will be returned.

    You can add or remove members from a group using the \u201cgroup update\u201d command. The user can use \u2018\u2013addMembers\u2019 to specify the addresses of the members to be added or \u2018\u2013removeMembers\u2019 to specify the addresses of the members to be removed.

    // create group\ngnfd-cmd group create gnfd://testGroup\n// update member\ngnfd-cmd group update --groupOwner 0x.. --addMembers 0x.. gnfd://testGroup\n
    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#policy-operation","title":"Policy Operation","text":"

    Users can run \u201c./gnfd-cmd policy -h \u201d to get help of permission operations.

    Users can use the \u201cpolicy put [RESOURCE-URL]\u201d command to assign resource permissions to other accounts or groups (called principal), such as the permission to delete objects. After the command executes successfully, the object policy information of the principal will be returned. The principal is set by \u2013groupId which indicates the group or \u2013grantee which indicates the account.

    The resource url can be the follow types:

    1) \u201cgrn:b::bucket-name\u201d, it indicates the bucket policy

    2) \u201cgrn:o::bucket-name/object-name\u201d, it indicates the object policy

    3) \u201cgrn:g:owner-address:group-name\u201d, it indicates the group policy

    // put object policy \ngnfd-cmd policy put --groupId 11 --actions get,delete grn:o::gnfd-bucket/gnfd-object\n\n// put bucket policy\ngnfd-cmd policy put --grantee 0x.. --actions delete  grn:b::gnfd-bucket\n

    Users can also revoke permission by \u201cpolicy delete\u201d command

    // delete the bucket policy from a group\ngnfd-cmd policy delete --groupId 11  grn:b::gnfd-bucket\n\n// delete the object policy from an grantee\ngnfd-cmd policy delete --grantee 0..  grn:o::gnfd-bucket/gnfd-object\n

    Users can list the policy of the grantee or group-id by \u201cpolicy ls\u201d command

    // list policy info of a group\ngnfd-cmd policy ls --groupId 11  grn:o::gnfd-bucket/gnfd-object\n

    In addition to the basic commands mentioned above, the Greenfield Command also supports functions such as transferring tokens and payment account operations. You can find more examples in the readme file of Greenfield Command.

    "},{"location":"bnb-greenfield/getting-started/token-transfer/","title":"BNB Transfer - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/token-transfer/#bridge-and-transfer-bnb","title":"Bridge and Transfer BNB","text":"

    The address formats of Greenfield and BSC are fully compatible. Users can transfer BNB between Greenfield and BSC freely. However, Greenfield only supports BNB and does not support BEP20 tokens currently.

    This is a comprehensive guide detailing the process of transferring BNB between Greenfield Blockchain and BSC.

    "},{"location":"bnb-greenfield/getting-started/token-transfer/#transfer-from-bsc-to-greenfield","title":"Transfer from BSC to Greenfield","text":"

    To perform a cross-chain transfer from BNB Smart Chain (BSC) to Greenfield, follow these steps:

    1. Visit Greenfield Bridge.

    2. Connect your wallet and switch to the BSC network.

    3. Specify the desired amount and click the Transfer In button.

    4. Confirm the transaction and wait for the transfer to be processed on BSC.

    5. Once the transaction is confirmed, the funds will be transferred from BSC to Greenfield. The transferred funds will reflect in the same account on Greenfield within a few seconds.

    You can also use DCellar and follow How to Transfer In to transfer BNBs from BSC to Greenfield.

    "},{"location":"bnb-greenfield/getting-started/token-transfer/#transfer-from-greenfield-to-bsc","title":"Transfer from Greenfield to BSC","text":"

    To perform a cross-chain transfer from Greenfield to BNB Smart Chain (BSC), you will need to:

    1. Visit Greenfield Bridge.

    2. Connect your wallet and switch to the Greenfield network.

    3. Specify the desired amount and click the Transfer Out button.

    4. Confirm the transaction and wait for the transfer to be processed on Greenfield.

    5. Once the transaction is confirmed, the funds will be transferred from Greenfield to BSC. The transferred funds will reflect in the same account on BSC within a few seconds.

    You can also use DCellar and follow How to Transfer Out to transfer BNBs from Greenfield to BSC.

    Note

    One thing to note is if the value of the cross-chain transfer is over 1000BNB, the funds will be locked in TokenHub for 12 hours before they can be withdrawn. Usually, a third-party server will help withdraw the unlocked token to the recipient, and users can also withdraw to the recipient themselves by following unlock document

    "},{"location":"bnb-greenfield/getting-started/token-transfer/#bnb-transfers-in-greenfield","title":"BNB Transfers in Greenfield","text":"

    Greenfield allows for easy and secure transfers between different accounts. However, due to the particularity of the transaction format, it is currently not possible to transfer tokens through the built-in Send function in the wallet, like MetaMask. To conduct an internal transfer within Greenfield, please adhere to the following steps:

    1. Visit DCellar.

    2. Click the Get Started button located at the top right.

    3. Connect your wallet and sign in.

    4. Go to the Wallet page on the left sidebar, then proceed to the Send page.

    5. Fill in the destination address where you want to transfer, specify the amount, and click the Send button.

    6. Confirm the transfer and wait for the transaction to be processed.

    7. Once the transfer is confirmed, the funds will be moved from the source account to the destination account within Greenfield.

    "},{"location":"bnb-greenfield/getting-started/wallet-configuration/","title":"Wallet Configuration - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/wallet-configuration/#wallet-configuration","title":"Wallet Configuration","text":"

    In this guide, you will learn how to use the extension wallets to interact with Greenfield. You can also add BNB Greenfield network according to the RPC Endpoints manually.

    "},{"location":"bnb-greenfield/getting-started/wallet-configuration/#supported-wallets","title":"Supported Wallets","text":"

    We assume you have installed Trust Wallet or MetaMask and have an account, if not, please refer to the download link of Trust Wallet and MetaMask to install it.

    "},{"location":"bnb-greenfield/getting-started/wallet-configuration/#add-greenfield-network","title":"Add Greenfield Network","text":"
    1. Visit BNB Chain List.

    2. Click Connect Wallet.

    1. Find Greenfield Mainnet or Greenfield Testnet, and click Add To Wallet to add new RPC in Trust Wallet or Metamask.

    1. When extension wallet prompts a window, click Approve.

    "},{"location":"bnb-greenfield/roadmap/features/","title":"Feature Lists - BNB Greenfield","text":""},{"location":"bnb-greenfield/roadmap/features/#feature-lists","title":"Feature Lists","text":"

    As a decentralized storage network, Greenfield provides a rich set of features and playability. This article documents the key features and their development status on Greenfield. Please stay tuned.

    Feature Name Description Status Ethereum compatible address Greenfield supports Ethereum compatible address format, which means users can continue to use Ethereum compatible wallets and accounts Mainnet EIP-712 transaction Support structured signature method of EIP-712, making the signed message user-readable Mainnet Governance Validators can vote on proposals through governance, including modification of various module parameters, validator joining and exiting, new SP joining, cross-chain contract parameters, etc. Mainnet Permission staking Support validator joining and exiting through governance, validator delegate/undelegate operations Mainnet Greenfield <-> BSC token transfer Support bidirectional cross-chain token transfer between BSC and Greenfield Mainnet SP basic operations Support new SP joining, viewing current SP, modifying SP information, and updating SP storage prices, etc. Mainnet Bucket operations Support creating/updating/deleting buckets Mainnet Object operations Support creating/uploading/downloading/deleting objects Mainnet Group operations Support creating/updating/deleting groups Mainnet Billing system Users need to pay storage and reading fees for objects stored on Greenfield. SPs earn corresponding income through corresponding storage services. Greenfield uses a stream payment method to calculate fees Mainnet Permission management Greenfield provides rich permission management functions, which can assetize data stored on it and open it to certain users. Greenfield supports adding or deleting permissions for individual users or groups at the bucket and object level Mainnet Resource mirror Greenfield supports mapping buckets, objects, and groups to BSC. There is a unique NFT on BSC corresponding to the data and resources, and developers can build various smart contract cross-chain management of resources on BSC, providing rich playability Mainnet Universal endpoint Users can access files stored on Greenfield through any SP in the SP network Mainnet Folder Greenfield supports prefix queries and delimiter queries for files within buckets, allowing dApps to organize folders on top of Greenfield Mainnet Data challenge Greenfield uses the data challenge scheme as a guarantee of data existence. Greenfield will randomly challenge the data segments stored on SPs. Users can also challenge any data segments stored on SPs to ensure that SPs correctly store their data Mainnet Data recovery Data recovery is used to ensure that the original data can be recovered when certain data is lost on SPs, ensuring the reliability of user data on Greenfield. Greenfield supports various forms of data recovery: 1. Data will be automatically recovered after data challenge succeeds. 2. Data will be automatically recovered when users find that the data is unreadable. 3. SPs can selectively recover some lost data through tools Mainnet Large object and breakpoint resume Greenfield supports breakpoint resume, which improves the efficiency and user experience of object transfer Mainnet SP graceful exit When SPs want to exit voluntarily for some reason, Greenfield can support SPs to migrate the previously stored data to other SPs and then exit, so that the freedom of SPs is ensured without affecting the availability of data on Greenfield Mainnet Migrate bucket Greenfield supports users to migrate their bucket from one SP to another Mainnet Expiration time for group member Greenfield supports setting expired time for group members Mainnet Link with opBNB Build native cross-chain bridge between Greenfield and opBNB Mainnet Resource tags Support setting tags for bucket, object, and group Mainnet Cross-chain permission module Enable add/delete permission from BSC/opBNB smart contracts Mainnet Atomic update Support update object other than delete and create again Testnet Greenfield as DA layer Make Greenfield as the DA layer of the other Blockchains such as opBNB and BSC Design Permanent Storage Support for permanent object storage Design Off Chain Auth Streamline off-chain authentication on Greenfield Mainnet SP as the upload agent Primary Storage Provider acts as the upload agent for object creation on Greenfield Mainnet Greenfield Storage Fee Paymaster A storage fee paymaster solution for sponsors to cover storage costs on Greenfield Mainnet Cross-Chain Programming Improve Greenfield cross-chain programming capability Mainnet"},{"location":"bnb-greenfield/roadmap/roadmap/","title":"Roadmap - BNB Greenfield","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#roadmap","title":"Roadmap","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#march-2023-testnet-congo","title":"March 2023, Testnet Congo","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#may-2023-testnet-mekong","title":"May 2023, Testnet Mekong","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#september-2023-launch-mainnet-lena","title":"September 2023, Launch Mainnet Lena","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#december-2023-mainnet","title":"December 2023, Mainnet","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#march-2024-mainnet","title":"March 2024, Mainnet","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#june-2024-mainnet","title":"June 2024, Mainnet","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#december-2024-mainnet","title":"December 2024, Mainnet","text":"

    For additional information, please refer to the BNB Greenfield Roadmap Proposal.

    "},{"location":"bnb-greenfield/storage-provider/overview/","title":"Overview - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/overview/#overview","title":"Overview","text":""},{"location":"bnb-greenfield/storage-provider/overview/#what-is-the-greenfield-storage-provider","title":"What is the Greenfield Storage Provider","text":"

    Storage Provider (SP) is an infrastructure provider for storage services. They work in synergy with Greenfield validators to provide a complete storage service. Validators store metadata and financial ledgers with consensus, while SPs store the actual data (payload data) of objects using the Greenfield chain as the ledger and single source of truth. SPs provide a range of convenient services for users and dApps to manage data on Greenfield.

    "},{"location":"bnb-greenfield/storage-provider/overview/#how-the-greenfield-storage-providers-works","title":"How the Greenfield Storage Providers works","text":"

    SPs need to register themselves firstly by depositing on the Greenfield blockchain as their Service Stake. The Greenfield validators will then conduct a governance procedure to vote to elect the SPs. When joining and leaving the network, SPs must follow specific actions to ensure data redundancy for users, or they will face fines on their Service Stake.

    SPs provide publicly accessible APIs that allow users to upload, download and manage data. These APIs are designed to be similar to Amazon S3 APIs, making it easier for existing developers to write code for them. SPs are responsible for responding to user requests to write (upload) and read (download) data, as well as managing user permissions and authentications.

    Each SP maintains its own local full node, allowing for a strong connection with the Greenfield network. This enables the SP to directly monitor state changes, properly index data, send transaction requests in a timely manner and manage local data accurately.

    To encourage SPs to showcase their capabilities and provide a professional storage system with high-quality SLA, it is recommended that they advertise their information and prove to the community.

    "},{"location":"bnb-greenfield/storage-provider/overview/#architecture","title":"Architecture","text":"Storage Provider Architecture

    SP contains fifteen core modules as shown below:

    "},{"location":"bnb-greenfield/storage-provider/overview/#how-to-implement-customized-requirements-in-greenfield-sp","title":"How to implement customized requirements in Greenfield SP","text":"

    From the code level, SP is not only an implementation layer, it has been expanded into a framework called GfSp, which allows users to implement their own logics according to their own needs. If users want to implement some specific functions, you can override these methods that are declared in the abstract interfaces. If users don\u2019t need to implement customized requirements, GfSp will use default implementations. There are nine important layers of abstraction:

    "},{"location":"bnb-greenfield/storage-provider/standard/","title":"Data Service Quality Standard - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/standard/#data-service-quality-standard","title":"Data Service Quality Standard","text":""},{"location":"bnb-greenfield/storage-provider/standard/#abstract","title":"Abstract","text":"

    BNB Greenfield is a decentralized storage network comprising two layers: blockchain and storage providers(SPs). The BNB Greenfield blockchain maintains ledgers for users and records storage metadata as common blockchain state data. SPs refer to storage service infrastructures provided by organizations or individuals.

    This standard aims to ensure SPs on Greenfield can provide enterprise-level, secure, reliable, and high-quality storage infrastructure and services to users. SPs that fail to meet the standards may have their eligibility and access revoked from the network.

    The standards consist of two parts:

    In addition to these standards, this document will introduce an official implementation of the SP protocols. Community developers are welcome to:

    "},{"location":"bnb-greenfield/storage-provider/standard/#minimum-service-quality-standards","title":"Minimum Service Quality Standards","text":""},{"location":"bnb-greenfield/storage-provider/standard/#capacity","title":"Capacity","text":""},{"location":"bnb-greenfield/storage-provider/standard/#availability","title":"Availability","text":"

    Greenfield will punish unavailable or poor quality SPs through challenge mechanisms. SPs with SLA below 99.9% or data durability below 99.99% are likely to be phased out.

    In the early stages of Greenfield, to encourage more inexperienced SPs to participate, Greenfield will apply a relatively relaxed slash mechanism to protect SPs from slashing more than 1 BNB within one hour.

    "},{"location":"bnb-greenfield/storage-provider/standard/#scalabilitybetter-to-have","title":"Scalability(better to have)","text":"

    We encourage SPs to dynamically scale up capacity on the basis of providing minimum capacity to avoid being unable to provide services due to sudden traffic and being slashed. The scaling strategy is related to the computing resource platform chosen by the SP. We do not make specific requirements in this regard.

    "},{"location":"bnb-greenfield/storage-provider/standard/#storage-provider-protocols","title":"Storage Provider Protocols","text":""},{"location":"bnb-greenfield/storage-provider/standard/#http-restful-api-specification","title":"HTTP RESTful API Specification","text":"

    Supporting the Greenfield Network API is essential for storage providers. It allows users and developers to interact and integrate with each SP node through a unified interface without having to adapt to custom interfaces from different SP nodes, greatly simplifying the user experience and development difficulty. The API includes functions to retrieve storage space information, upload and download files, and manage permissions.

    SP nodes can implement compatibility with the network API based on their own technology. Developers can refer to the Greenfield Network\u2019s open API documentation for interfacing development.

    "},{"location":"bnb-greenfield/storage-provider/standard/#universal-endpoint","title":"Universal Endpoint","text":"

    All storage objects in the Greenfield Network can be identified and accessed through a universal resource identifier (URI). When creating a storage object, the SP node needs to assign it a unique URI according to the network rules and support using that URI to retrieve the object.

    The detailed spec is defined here.

    "},{"location":"bnb-greenfield/storage-provider/standard/#auth-methods","title":"Auth Methods","text":"

    Permission management and authentication mechanisms are essential for a decentralized storage network, ensuring that only authorized users can access specific storage objects. The Greenfield Network defines standard permission divisions and authorization processes, requiring SP nodes to implement detailed permission control and user authentication accordingly. SP should achieve following three authentication at least:

    "},{"location":"bnb-greenfield/storage-provider/standard/#open-source-implementation","title":"Open source Implementation","text":"

    The open source storage provider framework implements the Greenfield storage provider API and protocol specifications. It provides standardized interfaces and abstractions for SP node developers, greatly reducing the difficulty of setting up a storage provider. Developers can quickly build SP based on this framework and conduct secondary development according to their business needs. This helps cultivate the developer ecosystem of the Greenfield Network and encourages more technical teams to join the construction of the Greenfield Network. Refer to the GitHub repo for more details.

    "},{"location":"bnb-greenfield/storage-provider/standard/#interfaces","title":"Interfaces","text":""},{"location":"bnb-greenfield/storage-provider/standard/#modules","title":"Modules","text":""},{"location":"bnb-greenfield/storage-provider/standard/#minimal-hardware-requirement","title":"Minimal Hardware Requirement","text":""},{"location":"bnb-greenfield/storage-provider/standard/#secondary-development-examples","title":"Secondary Development Examples","text":"

    Customize interface

    // new your own CustomizedPieceStore instance that implement the PieceStore interface\npieceStore := NewCustomizedPieceStore(...)\n\n// new GfSp framework app\ngfsp, err := NewGfSpBaseApp(GfSpConfig, CustomizePieceStore(pieceStore))\nif err != nil {\n    return err\n}\n\ngfsp.Start(ctx)\n\n// the GfSp framework will replace the default PieceStore with CustomizedPieceStore\n

    Customize module

    // new your own CustomizedApprover instance that implement the Approver interface\n// NewCustomizedApprover must be func type: \n// func(app *GfSpBaseApp, cfg *gfspconfig.GfSpConfig) (coremodule.Modular, error)\napprover := NewCustomizedApprover(GfSpBaseApp, GfSpConfig)\n\n// the Special Modular name is Predefined\ngfspapp.RegisterModularInfo(model.ApprovalModularName, model.ApprovalModularDescription, approver)\n\n// new GfSp framework app\ngfsp, err := NewGfSpBaseApp(GfSpConfig, CustomizeApprover(approver))\nif err != nil {\n    return err\n}\n\ngfsp.Start(ctx)\n// the GfSp framework will replace the default Approver with Customized Approver\n
    "},{"location":"bnb-greenfield/storage-provider/standard/#documents","title":"Documents","text":""},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/","title":"Storage Provider Lifecycle - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#storage-provider-lifecycle","title":"Storage Provider Lifecycle","text":"

    This document describes the entire lifecycle of a storage provider from joining the Greenfield Storage Network to exiting.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#preparation","title":"Preparation","text":"

    First, the storage provider needs to learn how to run and create a storage provider node, which requires several different user accounts and a unified external EndPoint.

    Note

    For more information, please see Run Storage Provider

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#proposal","title":"Proposal","text":"

    The Storage Provider (SP) must initiate an on-chain proposal that outlines the Msg information to be automatically executed after receiving approval through the voting process. Specifically, the Msg in this case is MsgCreateStorageProvider. It\u2019s essential to ensure that the deposit tokens exceed the minimum deposit tokens specified on the chain.

    Below are the required fields that need to be modified in the proposal:

    Note

    For more information, please see Add Storage Provider to Greenfield Network

    Initiating this on-chain proposal with the necessary modifications and deposits is a crucial step for the SP to become an active participant in the Greenfield network, offering reliable and secure storage services to users. By complying with the proposal requirements, the SP can enhance its reputation and attract more users, contributing to the growth and success of the decentralized storage ecosystem.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#in-service","title":"In Service","text":"

    During the in-service status, Storage Providers (SPs) actively engage in the network\u2019s daily operations. They handle a variety of user requests, including data storage, retrieval, and other storage-related operations.

    SPs assume a critical role in maintaining the availability, integrity, and confidentiality of the data they store. As gatekeepers of user access, they enforce proper authentication and authorization procedures to safeguard data from unauthorized access or tampering.

    At this stage, SPs must create virtual groups within the Greenfield network to efficiently serve buckets and objects. These virtual groups, resembling disk sectors, allow SPs to manage data storage in a more organized and optimized manner. By associating objects with virtual groups, SPs can limit the range of secondary storage providers responsible for storing object replica data, which enhances data redundancy and resilience.

    Note

    For more information, please see Virtual Group

    Additionally, SPs are required to provide corresponding stakes for the amount of data they store. This staking mechanism further incentivizes SPs to offer reliable and high-quality services to users. By staking tokens or digital assets, SPs demonstrate their commitment to maintaining a robust and trustworthy network, aligning their interests with the overall security and success of the storage ecosystem.

    Moreover, the creation of virtual groups and staking helps to disentangle the interdependency between buckets/objects and SPs. By doing so, SPs mitigate the need for an extensive volume of transactions when modifying on-chain BucketInfo and ObjectInfo during SP exits and bucket migrations. This leads to more efficient network management and smoother transitions during changes in the network\u2019s composition.

    As SPs continue to serve user needs and actively participate in network operations, their reputation and service quality become paramount. A positive reputation score is crucial for attracting more users to store their data with a particular SP. Through continuous improvement and adaptation, SPs can enhance their services, increase storage capacity, and maintain a competitive edge in the dynamic decentralized storage market.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#in-maintenance","title":"In Maintenance","text":"

    The maintenance mode for service providers (SPs) is a status in which SPs do not serve any create/upload requests from users. There are two circumstances in which an SP can be in maintenance mode:

    1. When an SP joins the network after a proposal has passed, it will stay in STATUS_IN_MAINTENANCE until it sends a transaction including msg MsgUpdateStorageProviderStatus to Greenfield to change its status to STATUS_IN_SERVICE.
    2. If an SP is already in service, it can send a transaction with msg MsgUpdateStorageProviderStatus to Greenfield and request a maintenance duration, if there are no restrictions violated, the SP is allowed to enter maintenance mode immediately.

    Note

    Note: The SP needs to send a transaction to Greenfield to update its status back STATUS_IN_SERVICE before its request duration ends, or Greenfield would do it mandatorily.

    There are two restrictions that apply when an SP requests to be in maintenance. These restrictions work with the parameters num_of_historical_blocks_for_maintenance_records, maintenance_duration_quota and num_of_lockup_blocks_for_maintenance. Refer to Params

    To ensure the quality of service provided, we strongly recommend that SPs conduct a self-test via the maintenance account before turning back to STATUS_IN_SERVICE. This includes creating buckets/objects to verify that all functionalities work as expected. For a detailed illustration on how to use SDK to create bucket/object, please refer to the APIs and SDKs.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#exit","title":"Exit","text":"

    There are two types of exit based on the behavior and choices of the SP: Graceful Exit and Forced Exit.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#graceful-exit","title":"Graceful Exit","text":"

    At some point, the SP may choose to voluntarily exit the Greenfield storage network for various reasons. Ensuring a graceful exit process is crucial to ensure a seamless transition of responsibilities and data to other SPs. During the exit process, the SP must continue to fulfill user serve user querying requests, Once the exit process is successfully completed, the SP can retrieve all the staked BNB.

    To execute a graceful exit, all its stored data need to be migrated to other successor SPs that are willing to take over. This data migration process involves recovering data from the exiting SP by successor SPs in a secure and efficient manner. After the exit SP sending a StorageProviderExit transaction to the Greenfield Blockchain, its status will turn to STATUS_GRACEFUL_EXITING. A successor SP can initiate the recovery process by first sending a ReserveSwapIn transaction to the Greenfield Blockchain, reserving the exit SP\u2019s position in the respective Global Virtual Group (GVG) or GVG Family so that it will be allowed to recover data from other SPs. Once the successor SP successfully takes over all data in a GVG or GVG Family, it will send a CompleteSwapIn transaction to the Greenfield Blockchain, confirming the completion of the data transfer process.

    Greenfield Blockchain incorporates an effective consensus mechanism to facilitate and validate the graceful exit process. This mechanism ensures that the exit is carried out transparently, maintaining the network\u2019s integrity and preventing any disruptions or data loss during the transition.

    To ensure the safe and reliable migration of data, frequent data challenges are applied to the SPs that take over the data. These challenges are designed to verify the integrity and consistency of the migrated data, reassuring users that their data remains secure and accessible.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#forced-exit","title":"Forced Exit","text":"

    An uncooperative SP no longer wishes to provide service and refuses to go through the standard graceful exit process. In such a case, Greenfield governance will force the SP to exit, make it enter STATUS_FORCED_EXITING. The data recovery process for successor SP is the same as graceful exit mentioned above. However, a forced exit SP will face penalties, and its staked BNB will be locked into the Payment module governance account, this payment account is used to receive forced settlement fee, and pay for potential debt from late forced settlement.

    Note

    For more information, please see SP exit

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/","title":"SP Common Issues - BNB Greenfield SP","text":"

    This is a list of solutions to common SP deployment issues

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#on-chain-proposal","title":"On-chain Proposal","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#1-why-send-tx-failed","title":"1. Why send tx failed?","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#2-why-is-proposal-rejected","title":"2. Why is Proposal Rejected?","text":"

    If your proposal received less than \u2154 of yes votes from validators, your propoosal will be rejected.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#3-why-is-proposal-failed","title":"3. Why is Proposal Failed","text":"

    To query the failed reason, run the following command:

    #  Greenfield Mainnet\n./gnfd query gov proposal <proposal-id> --node https://greenfield-chain-us.bnbchain.org:443\n\n# Greenfield Testnet\n./gnfd q gov proposal <proposal-id> --node https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org:443\n

    If you see the following message:

    failed_reason: 'spendable balance 999009992000000000000BNB is smaller than 1000000000000000000000BNB:\n

    It means the proposal initiator should be the funding address, and it should have balance of 1k BNB as deposit, according to above error msg.

    Please note the initial deposit requirement varies on different environments. see funding-address

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#sp-node-issues","title":"SP Node Issues","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#1-address-not-found-issue","title":"1. Address Not Found Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description","title":"Description","text":"

    After starting SP binary, see the following error:

    rpc error: code = NotFound desc = rpc error: code = NotFound desc = account 0x12334567890 not found: key not found\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause","title":"Root Cause","text":"

    It\u2019s not possiible to find information about a newly created address on chain.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution","title":"Solution","text":"

    Before starting your SP, transfer BNB to all of your 5 addresses.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#2-database-configuration-issue","title":"2. Database Configuration Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_1","title":"Description","text":"

    After starting SP binary, see the following error:

    Table \"block_syncer.master_db\" does not exist\nFailed to get db config from config file\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_1","title":"Root Cause","text":"

    Data source name(dsn) is not set in config.toml.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_1","title":"Solution","text":"
    [BlockSyncer]\nModules = ['epoch','bucket','object','payment','group','permission','storage_provider','prefix_tree', 'virtual_group','sp_exit_events','object_id_map','general']\nDsn = [BsDB_User]:[BsDB_Passwd]@tcp([BsDB_Address])/[BsDB_Database?parseTime=true&multiStatements=true&loc=Local&interpolateParams=true\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#3-object-sealed-state-issue","title":"3. Object Sealed State Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_2","title":"Description","text":"

    After uploading a file, you see an error message:

    Message: object has not been sealed state\n

    From SP log, you see the following:

    {\"t\":\"2023-07-10T11:34:50.856+0800\",\"l\":\"error\",\"caller\":\"gfspapp/sign_server.go:42\",\"msg\":\"failed to seal object\",\"error\":\"code_space:\\\"signer\\\" http_status_code:400 inner_code:120002 description:\\\"failed to broadcast seal object tx, error: failed to broadcast tx, resp code: 13\\\" \"}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_2","title":"Root Cause","text":"

    SealAddress does not have enough BNB to sign seal transactions

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_2","title":"Solution","text":"

    Transfer BNB to SealAddress.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#4-p2p-issue","title":"4. P2P Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_3","title":"Description","text":"

    After starging SP binary, you see an error message:

    failed to parse address 'k8s-gftestne-p2pexter-bc25ac70bc-a31e9596d87054c3.elb.us-east-1.amazonaws.com:9933' domain\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_3","title":"Root Cause","text":"

    SP is trying to get connected with invalid SP URL in P2P network

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_3","title":"Solution","text":"

    Update [P2P] setting in config.toml:

    [P2P]\n# p2p node msg Secp256k1 encryption key, it is different from other SP's addresses\nP2PPrivateKey = '${p2p_private_key}'\nP2PAddress = '0.0.0.0:9933'\nP2PAntAddress = '${load_balance_doamin:port}'\nP2PBootstrap = []\nP2PPingPeriod = 0\n

    P2PAntAddress is your load balance address. If you don\u2019t have a load balance address, you should have a public IP and use it in P2PAddress. P2PBootstrap is not used anymore, you can leave this field empty.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#5minio-authentication-issue","title":"5.MinIO Authentication Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_4","title":"Description","text":"

    Cannot config Minio as storage

    {\"t\":\"2023-07-17T18:05:40.245+0800\",\"l\":\"debug\",\"caller\":\"storage/object_storage.go:15\",\"msg\":\"created minio storage at endpoint http://172.17.0.2:9000/hashquark\"}\nJul 17 18:05:41 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:05:40.245+0800\",\"l\":\"info\",\"caller\":\"storage/minio.go:37\",\"msg\":\"new minio store succeeds\",\"bucket\":\"hashquark\"}\nJul 17 18:07:01 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:07:00.893+0800\",\"l\":\"error\",\"caller\":\"storage/s3.go:147\",\"msg\":\"S3 failed to head bucket\",\"error\":\"NoCredentialProviders: no valid providers in chain. Deprecated.\\n\\tFor verbose messaging see aws.Config.CredentialsChainVerboseErrors\"}\nJul 17 18:07:01 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:07:00.893+0800\",\"l\":\"error\",\"caller\":\"piece/piece_store.go:88\",\"msg\":\"failed to head bucket\",\"error\":\"NoCredentialProviders: no valid providers in chain. Deprecated.\\n\\tFor verbose messaging see aws.Config.CredentialsChainVerboseErrors\"}\nJul 17 18:07:01 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:07:00.893+0800\",\"l\":\"error\",\"caller\":\"piece/piece_store.go:77\",\"msg\":\"failed to check bucket due to storage is not configured rightly \",\"error\":\"deny access bucket\",\"object\":\"minio://hashquark/\"}\nJul 17 18:07:01 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:07:00.893+0800\",\"l\":\"error\",\"caller\":\"piece/piece_store.go:21\",\"msg\":\"failed to create storage\",\"error\":\"deny access bucket\"}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_4","title":"Root Cause","text":"

    This is a MinIO authentication

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_4","title":"Solution","text":"

    You can refer here.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#6-sp-standard-test-issue","title":"6. SP Standard Test Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_5","title":"Description","text":"
    2023/07/26 19:06:03.543395 [INFO] GID 41, Uploading file - object: 2q4l5v4v3z, bucket: sc1bw\ndefault error msg : <html>\n<head><title>413 Request Entity Too Large</title></head>\n<body>\n<center><h1>413 Request Entity Too Large</h1></center>\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\n</body>\n</html>\n{\"level\":\"error\",\"time\":\"2023-07-26T13:06:03-06:00\",\"message\":\"do API error, url: https://sc1bw.gnfd-testnet-sp.epotter-qa.io/2q4l5v4v3z, err: statusCode 413 : code : unknown error  request-id  (Message: <html>\\r\\n<head><title>413 Request Entity Too Large</title></head>\\r\\n<body>\\r\\n<center><h1>413 Request Entity Too Large</h1></center>\\r\\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\\r\\n</body>\\r\\n</html>)\"}\n2023/07/26 19:06:03.543395 [INFO] GID 41, Uploading file - object: 2q4l5v4v3z, bucket: sc1bw\ndefault error msg : <html>\n<head><title>413 Request Entity Too Large</title></head>\n<body>\n<center><h1>413 Request Entity Too Large</h1></center>\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\n</body>\n</html>\n{\"level\":\"error\",\"time\":\"2023-07-26T13:06:03-06:00\",\"message\":\"do API error, url: https://sc1bw.gnfd-testnet-sp.epotter-qa.io/2q4l5v4v3z, err: statusCode 413 : code : unknown error  request-id  (Message: <html>\\r\\n<head><title>413 Request Entity Too Large</title></head>\\r\\n<body>\\r\\n<center><h1>413 Request Entity Too Large</h1></center>\\r\\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\\r\\n</body>\\r\\n</html>)\"}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_5","title":"Root Cause","text":"

    Nginx does not support large file

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_5","title":"Solution","text":"

    Enlarge proxy-boody-size

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#dcellar-integration-issues","title":"DCellar Integration Issues","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#1-no-access-control-allow-origin-header-is-present-on-the-requested-resource","title":"1. No \u2018Access-Control-Allow-Origin\u2019 header is present on the requested resource","text":"

    Error:

    Access to XMLHttpRequest at 'https://fbgtest.gnfd-testnet-sp.fbgx.ai/?read-quota&year-month=2023-07' from origin 'https://dcellar.io' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_6","title":"Solution","text":"

    Add these headers

    Access-Control-Allow-Credentials:\ntrue\nAccess-Control-Allow-Headers:\nAccess-Control-Allow-Headers: DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-MD5,Range,Authorization,X-Gnfd-Content-Sha256,X-Gnfd-Unsigned-Msg,X-Gnfd-Txn-Hash,Date,X-Gnfd-Object-ID,X-Gnfd-Resource,X-Gnfd-Piece-Index,X-Gnfd-Redundancy-Index,Address,X-Gnfd-User-Address,X-Gnfd-App-Domain,X-Gnfd-App-Reg-Nonce,X-Gnfd-Date,X-Gnfd-App-Reg-Public-Key,X-Gnfd-App-Reg-Expiry-Date,X-Gnfd-Expiry-Timestamp\nAccess-Control-Allow-Methods:\nGET, PUT, POST, DELETE, PATCH, OPTIONS\nAccess-Control-Allow-Origin:\n*\nAccess-Control-Expose-Headers:\n*, X-Gnfd-Request-ID,X-Gnfd-Signed-Msg,X-Gnfd-Object-ID,X-Gnfd-Integrity-Hash,X-Gnfd-Piece-Hash\nAccess-Control-Max-Age:\n1728000\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#2-when-an-option-request-is-made-i-get-options-405-method-not-allowed-error","title":"2. when an OPTION request is made, I get OPTIONS 405 (Method Not Allowed) error","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_6","title":"Root cause","text":"

    The 405 Method Not Allowed error occurs when the web server is configured in a way that does not allow you to perform a specific action for a particular URL. It\u2019s an HTTP response status code that indicates that the request method is known by the server but is not supported by the target resource.The 405 Method Not Allowed error occurs when the web server is configured in a way that does not allow you to perform a specific action for a particular URL. It\u2019s an HTTP response status code that indicates that the request method is known by the server but is not supported by the target resource.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_7","title":"Solution","text":"

    Your application is likely running on a server using one of these three popular webserver software: Apache, nginx, or Cloudflare. Check your configuration files for your web server software for unintentional redirect or request handling instructions.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/","title":"SP Compiling and Dependencies - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#compile-sp","title":"Compile SP","text":"

    Compilation dependencies:

    # clone source code\ngit clone https://github.com/bnb-chain/greenfield-storage-provider.git\n\ncd greenfield-storage-provider/\n\n# install dependent tools: buf, protoc-gen-gocosmos and mockgen\nmake install-tools\n\n# compile sp\nmake build\n\n# move to build directory\ncd build\n\n# execute gnfd-sp binary file\n./gnfd-sp version\n\n# show the gnfd-sp version information\nGreenfield Storage Provider\n    __                                                       _     __\n    _____/ /_____  _________ _____ ____     ____  _________ _   __(_)___/ /__  _____\n    / ___/ __/ __ \\/ ___/ __  / __  / _ \\   / __ \\/ ___/ __ \\ | / / / __  / _ \\/ ___/\n    (__  ) /_/ /_/ / /  / /_/ / /_/ /  __/  / /_/ / /  / /_/ / |/ / / /_/ /  __/ /\n    /____/\\__/\\____/_/   \\__,_/\\__, /\\___/  / .___/_/   \\____/|___/_/\\__,_/\\___/_/\n    /____/       /_/\n\nVersion : v1.0.0\nBranch  : master\nCommit  : 7e1f56809c5385bf1ea6f41d318ab1419dcb0f86\nBuild   : go1.20.3 darwin arm64 2023-10-08 10:31\n\n# show the gnfd-sp help info\n./gnfd-sp -h\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#note","title":"Note","text":"

    If you\u2019ve already executed make install-tools command in your shell, but you failed to make build and encountered one of the following error messages:

    # error message 1\nbuf: command not found\n# you can execute the following command, assumed that you installed golang in /usr/local/go/bin. Other OS are similar.\nGO111MODULE=on GOBIN=/usr/local/go/bin go install github.com/bufbuild/buf/cmd/buf@v1.25.0\n\n# error message 2\nFailure: plugin gocosmos: could not find protoc plugin for name gocosmos - please make sure protoc-gen-gocosmos is installed and present on your $PATH\n# you can execute the fowllowing command, assumed that you installed golang in /usr/local/go/bin. Other OS are similar.\nGO111MODULE=on GOBIN=/usr/local/go/bin go install github.com/cosmos/gogoproto/protoc-gen-gocosmos@latest\n\n# if you want to execute unit test of sp, you should execute the following command, assumed that you installed golang in /usr/local/go/bin. Other OS are similar.\nGO111MODULE=on GOBIN=/usr/local/go/bin go install go.uber.org/mock/mockgen@latest\n

    Above error messages are due to users don\u2019t set go env correctly. More info users can search GOROOT, GOPATH and GOBIN.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#sp-dependencies","title":"SP Dependencies","text":"

    If a user wants to start SP in local mode or testnet mode, you must prepare SPDB, BSDB and PieceStore dependencies.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#spdb-and-bsdb","title":"SPDB and BSDB","text":"

    SP uses SPDB and BSDB to store some metadata such as object info, object integrity hash, etc. These two DBs now use RDBMS to complete corresponding function.

    Users now can use MySQL or MariaDB to store metadata.The following lists the supported RDBMS:

    1. MySQL
    2. MariaDB

    More types of database such as PostgreSQL or NewSQL will be supported in the future.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#piecestore","title":"PieceStore","text":"

    Greenfield is a decentralized data storage system which uses object storage as the main data storage system. SP encapsulates data storage as PieceStore which provides common interfaces to be compatible with multiple data storage systems. Therefore, if a user wants to join SP or test the function of SP, you must use a data storage system.

    The following lists the supported data storage systems:

    1. AWS S3: An object storage can be used in production environment.
    2. Aliyun OSS: Fully managed object storage service to store and access any amount of data from anywhere.
    3. B2: Backblaze B2 provides unlimited data storage in the cloud at \u2155th the cost of Amazon S3.
    4. MinIO: An object storage can be used in production environment which is compatible with AWS S3.
    5. POSIX Filesystem: Local filesystem is used for experiencing the basic features of SP and understanding how SP works. The piece data created by SP cannot be got within the network and can only be used on a single machine.

    Detailed info about PieceStore, you can refer this doc.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#install-dependencies","title":"Install Dependencies","text":""},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#install-mysql-in-centos","title":"Install MySQL in CentOS","text":"
    1. Install MySQL yum package
    # 1. Download MySQL yum package\nwget http://repo.mysql.com/mysql57-community-release-el7-10.noarch.rpm\n\n# 2. Install MySQL source\nrpm -Uvh mysql57-community-release-el7-10.noarch.rpm\n\n# 3. Install public key\nrpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022\n\n# 4. Install MySQL server\nyum install -y mysql-community-server\n\n# 5. Start MySQL\nsystemctl start mysqld.service\n\n# 6. Check whether the startup is successful\nsystemctl status mysqld.service\n\n# 7. Get temporary password\ngrep 'temporary password' /var/log/mysqld.log \n\n# 8. Login MySQL through temporary password\n# After you log in with the temporary password, do not perform any other operations. Otherwise, an error will occur. In this case, you need to change the password\nmysql -uroot -p\n\n# 9. change MySQL password rules\nmysql> set global validate_password_policy=0;\nmysql> set global validate_password_length=1;\nmysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'yourpassword';\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/","title":"SP Config - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/run-book/config/#sp-config","title":"SP Config","text":"

    This section gives you a complete config of SP. ./gnfd-sp config.dump will generate a template config.toml.

    # optional\nEnv = ''\n# optional\nAppID = ''\n# optional\nServer = []\n# optional\nGRPCAddress = ''\n\n[SpDB]\n# required\nUser = ''\n# required\nPasswd = ''\n# required\nAddress = ''\n# required\nDatabase = ''\n# optional\nConnMaxLifetime = 0\n# optional\nConnMaxIdleTime = 0\n# optional\nMaxIdleConns = 0\n# optional\nMaxOpenConns = 0\n# optional\nEnableTracePutEvent = false\n\n[BsDB]\n# required\nUser = ''\n# required\nPasswd = ''\n# required\nAddress = ''\n# required\nDatabase = ''\n# optional\nConnMaxLifetime = 0\n# optional\nConnMaxIdleTime = 0\n# optional\nMaxIdleConns = 0\n# optional\nMaxOpenConns = 0\n# optional\nEnableTracePutEvent = false\n\n[PieceStore]\n# required\nShards = 0\n\n[PieceStore.Store]\n# required\nStorage = ''\n# optional\nBucketURL = ''\n# optional\nMaxRetries = 0\n# optional\nMinRetryDelay = 0\n# optional\nTLSInsecureSkipVerify = false\n# required\nIAMType = ''\n\n[Chain]\n# required\nChainID = ''\n# required\nChainAddress = []\n# optional\nSealGasLimit = 0\n# optional\nSealFeeAmount = 0\n# optional\nRejectSealGasLimit = 0\n# optional\nRejectSealFeeAmount = 0\n# optional\nDiscontinueBucketGasLimit = 0\n# optional\nDiscontinueBucketFeeAmount = 0\n# optional\nCreateGlobalVirtualGroupGasLimit = 0\n# optional\nCreateGlobalVirtualGroupFeeAmount = 0\n# optional\nCompleteMigrateBucketGasLimit = 0\n# optional\nCompleteMigrateBucketFeeAmount = 0\n\n[SpAccount]\n# required\nSpOperatorAddress = ''\n# required\nOperatorPrivateKey = ''\n# optional\nFundingPrivateKey = ''\n# required\nSealPrivateKey = ''\n# required\nApprovalPrivateKey = ''\n# required\nGcPrivateKey = ''\n# required\nBlsPrivateKey = ''\n\n[Endpoint]\n# required\nApproverEndpoint = ''\n# required\nManagerEndpoint = ''\n# required\nDownloaderEndpoint = ''\n# required\nReceiverEndpoint = ''\n# required\nMetadataEndpoint = ''\n# required\nUploaderEndpoint = ''\n# required\nP2PEndpoint = ''\n# required\nSignerEndpoint = ''\n# required\nAuthenticatorEndpoint = ''\n\n[Approval]\n# optional\nBucketApprovalTimeoutHeight = 0\n# optional\nObjectApprovalTimeoutHeight = 0\n# optional\nReplicatePieceTimeoutHeight = 0\n\n[Bucket]\n# optional\nAccountBucketNumber = 0\n# optional\nMaxListReadQuotaNumber = 0\n# optional\nMaxPayloadSize = 0\n\n[Gateway]\n# required\nDomainName = ''\n# required\nHTTPAddress = ''\n\n[Executor]\n# optional\nMaxExecuteNumber = 0\n# optional\nAskTaskInterval = 0\n# optional\nAskReplicateApprovalTimeout = 0\n# optional\nAskReplicateApprovalExFactor = 0.0\n# optional\nListenSealTimeoutHeight = 0\n# optional\nListenSealRetryTimeout = 0\n# optional\nMaxListenSealRetry = 0\n# optional\nMaxObjectMigrationRetry = 0\n# optional\nObjectMigrationRetryTimeout = 0\n# optional\nEnableSkipFailedToMigrateObject = false\n# optional\nBucketTrafficKeepTimeDay = 0\n# optional\nReadRecordKeepTimeDay = 0\n# optional\nReadRecordDeleteLimit = 0\n\n[P2P]\n# optional\nP2PPrivateKey = ''\n# optional\nP2PAddress = ''\n# optional\nP2PAntAddress = ''\n# optional\nP2PBootstrap = []\n# optional\nP2PPingPeriod = 0\n\n[Parallel]\n# optional\nGlobalCreateBucketApprovalParallel = 0\n# optional\nGlobalCreateObjectApprovalParallel = 0\n# optional\nGlobalMaxUploadingParallel = 0\n# optional\nGlobalUploadObjectParallel = 0\n# optional\nGlobalReplicatePieceParallel = 0\n# optional\nGlobalSealObjectParallel = 0\n# optional\nGlobalReceiveObjectParallel = 0\n# optional\nGlobalRecoveryPieceParallel = 0\n# optional\nGlobalMigrateGVGParallel = 0\n# optional\nGlobalBackupTaskParallel = 0\n# optional\nGlobalDownloadObjectTaskCacheSize = 0\n# optional\nGlobalChallengePieceTaskCacheSize = 0\n# optional\nGlobalSyncConsensusInfoInterval = 0\n# optional\nGlobalGCObjectParallel = 0\n# optional\nGlobalGCBucketMigrationParallel = 0\n# optional\nGlobalGCZombieParallel = 0\n# optional\nGlobalGCMetaParallel = 0\n# optional\nUploadObjectParallelPerNode = 0\n# optional\nReceivePieceParallelPerNode = 0\n# optional\nDownloadObjectParallelPerNode = 0\n# optional\nChallengePieceParallelPerNode = 0\n# optional\nAskReplicateApprovalParallelPerNode = 0\n# optional\nQuerySPParallelPerNode = 0\n# required\nDiscontinueBucketEnabled = false\n# optional\nDiscontinueBucketTimeInterval = 0\n# required\nDiscontinueBucketKeepAliveDays = 0\n# optional\nLoadReplicateTimeout = 0\n# optional\nLoadSealTimeout = 0\n\n[Task]\n# optional\nUploadTaskSpeed = 0\n# optional\nDownloadTaskSpeed = 0\n# optional\nReplicateTaskSpeed = 0\n# optional\nReceiveTaskSpeed = 0\n# optional\nSealObjectTaskTimeout = 0\n# optional\nSealObjectTaskRetry = 0\n# optional\nReplicateTaskRetry = 0\n# optional\nReceiveConfirmTaskRetry = 0\n# optional\nGcObjectTaskTimeout = 0\n# optional\nGcZombieTaskTimeout = 0\n# optional\nGcMetaTaskTimeout = 0\n# optional\nGcObjectTaskRetry = 0\n# optional\nGcZombieTaskRetry = 0\n# optional\nGcMetaTaskRetry = 0\n\n[Monitor]\n# required\nDisableMetrics = false\n# required\nDisablePProf = false\n# required\nDisableProbe = false\n# required\nMetricsHTTPAddress = ''\n# required\nPProfHTTPAddress = ''\n# required\nProbeHTTPAddress = ''\n\n# optional\n[Rcmgr]\n# optional\nDisableRcmgr = false\n\n[Log]\n# optional\nLevel = ''\n# optional\nPath = ''\n\n[BlockSyncer]\n# required\nModules = ['epoch','bucket','object','payment','group','permission','storage_provider','prefix_tree','virtual_group','sp_exit_events','object_id_map','general']\n# required\nWorkers = 0\n# optional\nBsDBWriteAddress = ''\n\n[APIRateLimiter]\n# every line should represent one entry of gateway route. The comment after each line must contain which route name it represents.\n# Most of APIs has a qps number, offered by QA team.  That usually means the max qps for the whole 4 gateway cluster.\n# How to setup the RateLimit value, it is a sophistcated question and need take a lot of factors into account.\n# 1. For most query-APIs, we can setup a rate limit up to the 1/4 of max qps, as the config is for only one gateway instance.\n# 2. Also we avoid to setup a too large or too small rate limit value.\n# 3. For upload/download APIs, it is diffiult to use a rate limit as a protect mechanism for the servers. Because the performance of upload/download interactions usually dependens on how large the file is processed.\n# 4. We tetatively setup 50~75 as the rate limit for the download/upload APIs and we can ajdust them once we have a better experience.\n# 5. Currently, please only put one name inside the name list of PathPatttern\n\n# optional\nPathPattern = [\n  {Key = \"/auth/request_nonce\", Method = \"GET\", Names = [\"GetRequestNonce\"]},\n  {Key = \"/auth/update_key\", Method = \"POST\", Names = [\"UpdateUserPublicKey\"]},\n  {Key = \"/permission/.+/[^/]*/.+\", Method = \"GET\", Names = [\"VerifyPermission\"]},\n  {Key = \"/greenfield/admin/v1/get-approval\", Method = \"GET\", Names = [\"GetApproval\"]},\n  {Key = \"/greenfield/admin/v1/challenge\", Method = \"GET\", Names = [\"GetChallengeInfo\"]},\n  {Key = \"/greenfield/admin/v2/challenge\", Method = \"GET\", Names = [\"GetChallengeInfo\"]},\n  {Key = \"/greenfield/receiver/v1/replicate-piece\", Method = \"PUT\", Names = [\"ReplicateObjectPiece\"]},\n  {Key = \"/greenfield/recovery/v1/get-piece\", Method = \"GET\", Names = [\"RecoveryPiece\"]},\n  {Key = \"/greenfield/migrate/v1/notify-migrate-swap-out-task\", Method = \"POST\", Names = [\"NotifyMigrateSwapOut\"]},\n  {Key = \"/greenfield/migrate/v1/migrate-piece\", Method = \"GET\", Names = [\"MigratePiece\"]},\n  {Key = \"/greenfield/migrate/v1/migration-bucket-approval\", Method = \"GET\", Names = [\"MigrationBucketApproval\"]},\n  {Key = \"/greenfield/migrate/v1/get-swap-out-approval\", Method = \"GET\", Names = [\"SwapOutApproval\"]},\n  {Key = \"/download/[^/]*/.+\", Method = \"GET\", Names = [\"DownloadObjectByUniversalEndpoint\"]},{Key = \"/download\", Method = \"GET\", Names = [\"DownloadObjectByUniversalEndpoint\"]},\n  {Key = \"/view/[^/]*/.+\", Method = \"GET\", Names = [\"ViewObjectByUniversalEndpoint\"]},{Key = \"/view\", Method = \"GET\", Names = [\"ViewObjectByUniversalEndpoint\"]},\n  {Key = \"/status\", Method = \"GET\", Names = [\"GetStatus\"]},\n  {Key = \"/.+/.+[?]offset.*\", Method = \"POST\", Names = [\"ResumablePutObject\"]},\n  {Key = \"/.+/.+[?]upload-context.*\", Method = \"GET\", Names = [\"QueryResumeOffset\"]},\n  {Key = \"/.+/.+[?]upload-progress.*\", Method = \"GET\", Names = [\"QueryUploadProgress\"]},\n  {Key = \"/.+/.+[?]bucket-meta.*\", Method = \"GET\", Names = [\"GetBucketMeta\"]},\n  {Key = \"/.+/.+[?]object-meta.*\", Method = \"GET\", Names = [\"GetObjectMeta\"]},\n  {Key = \"/.+/.+[?]object-policies.*\", Method = \"GET\", Names = [\"ListObjectPolicies\"]},\n  {Key = \"/.+[?]read-quota.*\", Method = \"GET\", Names = [\"GetBucketReadQuota\"]},\n  {Key = \"/.+[?]list-read-quota.*\", Method = \"GET\", Names = [\"ListBucketReadRecord\"]},\n  {Key = \"/[?].*group-query.*\", Method = \"GET\", Names = [\"GetGroupList\"]},\n  {Key = \"/[?].*objects-query.*\", Method = \"GET\", Names = [\"ListObjectsByIDs\"]},\n  {Key = \"/[?].*buckets-query.*\", Method = \"GET\", Names = [\"ListBucketsByIDs\"]},\n  {Key = \"/[?].*verify-id.*\", Method = \"GET\", Names = [\"VerifyPermissionByID\"]},\n  {Key = \"/[?].*user-groups.*\", Method = \"GET\", Names = [\"GetUserGroups\"]},\n  {Key = \"/[?].*group-members.*\", Method = \"GET\", Names = [\"GetGroupMembers\"]},\n  {Key = \"/[?].*owned-groups.*\", Method = \"GET\", Names = [\"GetUserOwnedGroups\"]},\n\n  {Key = \"/.+/$\", Method = \"GET\", Names = [\"ListObjectsByBucket\"]},\n  {Key = \"/.+/[?].*\", Method = \"GET\", Names = [\"ListObjectsByBucket\"]},\n  {Key = \"/.+/.+\", Method = \"GET\", Names = [\"GetObject\"]},\n  {Key = \"/.+/.+\", Method = \"PUT\", Names = [\"PutObject\"]},\n  {Key = \"/$\", Method = \"GET\", Names = [\"GetUserBuckets\"]},\n  {Key = \"/[?].*\", Method = \"GET\", Names = [\"GetUserBuckets\"]},\n\n]\n\nNameToLimit = [\n  {Name = \"GetRequestNonce\", RateLimit = 100, RatePeriod = 'S'}, # requestNonceRouterName 3000qps\n  {Name = \"UpdateUserPublicKey\", RateLimit = 100, RatePeriod = 'S'}, # updateUserPublicKeyRouterName 4000qps\n  {Name = \"VerifyPermission\", RateLimit = 100, RatePeriod = 'S'}, # verifyPermissionRouterName  1200qps\n  {Name = \"GetApproval\", RateLimit = 35, RatePeriod = 'S'}, # approvalRouterName  150qps\n  {Name = \"GetChallengeInfo\", RateLimit = 20, RatePeriod = 'S'}, # getChallengeInfoRouterName, no test data\n  {Name = \"ReplicateObjectPiece\", RateLimit = 1000, RatePeriod = 'S'},  # replicateObjectPieceRouterName, no test data. Internal API among sps, no rate limit is needed.\n  {Name = \"RecoveryPiece\", RateLimit = 1000, RatePeriod = 'S'}, # recoveryPieceRouterName, no test data. Internal API among sps, no rate limit is needed.\n  {Name = \"NotifyMigrateSwapOut\", RateLimit = 10, RatePeriod = 'S'},  # notifyMigrateSwapOutRouterName, no test data. Internal API among sps, no rate limit is needed.\n  {Name = \"MigratePiece\", RateLimit = 10, RatePeriod = 'S'}, # migratePieceRouterName, no test data\n  {Name = \"MigrationBucketApproval\", RateLimit = 10, RatePeriod = 'S'}, # migrationBucketApprovalName, no test data\n  {Name = \"SwapOutApproval\", RateLimit = 10, RatePeriod = 'S'}, # swapOutApprovalName, no test data\n  {Name = \"DownloadObjectByUniversalEndpoint\", RateLimit = 50, RatePeriod = 'S'}, # downloadObjectByUniversalEndpointName, 50qps\n  {Name = \"ViewObjectByUniversalEndpoint\", RateLimit = 50, RatePeriod = 'S'}, # viewObjectByUniversalEndpointName, 50qps\n  {Name = \"GetStatus\", RateLimit = 200, RatePeriod = 'S'},# getStatusRouterName, 2000qps\n  {Name = \"ResumablePutObject\", RateLimit = 30, RatePeriod = 'S'}, # resumablePutObjectRouterName , test data is same as putObject object 10qps\n  {Name = \"QueryResumeOffset\", RateLimit = 30, RatePeriod = 'S'},  # queryResumeOffsetName, test data is same as putObject object 10qps\n  {Name = \"QueryUploadProgress\", RateLimit = 50, RatePeriod = 'S'}, # queryUploadProgressRouterName, test data is same as putObject object 10qps\n  {Name = \"GetBucketMeta\", RateLimit = 100, RatePeriod = 'S'}, # getBucketMetaRouterName, 400qps\n  {Name = \"GetObjectMeta\", RateLimit = 100, RatePeriod = 'S'}, # getObjectMetaRouterName, 400qps\n  {Name = \"ListObjectPolicies\", RateLimit = 200, RatePeriod = 'S'}, # listObjectPoliciesRouterName, 2000qps\n  {Name = \"GetBucketReadQuota\", RateLimit = 200, RatePeriod = 'S'}, # getBucketReadQuotaRouterName\n  {Name = \"ListBucketReadRecord\", RateLimit = 100, RatePeriod = 'S'}, # listBucketReadRecordRouterName\n  {Name = \"GetGroupList\", RateLimit = 200, RatePeriod = 'S'}, # getGroupListRouterName\uff0c similar to getUserGroupsRouterName, 2000qps\n  {Name = \"ListObjectsByIDs\", RateLimit = 200, RatePeriod = 'S'}, # listObjectsByIDsRouterName, 1200qps\n  {Name = \"ListBucketsByIDs\", RateLimit = 200, RatePeriod = 'S'}, # listBucketsByIDsRouterName, 2000qps\n  {Name = \"VerifyPermissionByID\", RateLimit = 200, RatePeriod = 'S'}, # verifyPermissionByIDRouterName, 1200qps\n  {Name = \"GetUserGroups\", RateLimit = 200, RatePeriod = 'S'}, # getUserGroupsRouterName, 2000qps\n  {Name = \"GetGroupMembers\", RateLimit = 200, RatePeriod = 'S'}, # getGroupMembersRouterName, 2000qps\n  {Name = \"GetUserOwnedGroups\", RateLimit = 200, RatePeriod = 'S'}, # getUserOwnedGroupsRouterName, 2000qps\n\n  {Name = \"ListObjectsByBucket\", RateLimit = 75, RatePeriod = 'S'}, # listObjectsByBucketRouterName, 300qps\n  {Name = \"GetObject\", RateLimit = 75, RatePeriod = 'S'}, # getObjectRouterName, 100 qps\n  {Name = \"PutObject\", RateLimit = 75, RatePeriod = 'S'}, # putObjectRouterName, 100 qps\n  {Name = \"GetUserBuckets\", RateLimit = 75, RatePeriod = 'S'}] # getUserBucketsRouterName, 1000 qps\n\nHostPattern = []\n\n[Manager]\n# optional\nEnableLoadTask = false\n# optional\nEnableHealthyChecker = false\n# optional\nSubscribeSPExitEventIntervalMillisecond = 0\n# optional\nSubscribeSwapOutExitEventIntervalMillisecond = 0\n# optional\nSubscribeBucketMigrateEventIntervalMillisecond = 0\n# optional\nGVGPreferSPList = []\n# optional\nSPBlackList = []\n# optional\nEnableTaskRetryScheduler = false\n# optional\nRejectUnsealThresholdSecond = 0\n\n[GC]\n# optional\nGCObjectTimeInterval = 0\n# optional\nGCObjectBlockInterval = 0\n# optional\nGCObjectSafeBlockDistance = 0\n# optional\nEnableGCZombie = false\n# optional\nGCZombieSafeObjectIDDistance = 0\n# optional\nGCZombiePieceTimeInterval = 0\n# optional\nGCZombiePieceObjectIDInterval = 0\n# optional\nEnableGCMeta = false\n# optional\nGCMetaTimeInterval = 0\n\n[Quota]\n# optional\nMonthlyFreeQuota = 0\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#app-info","title":"App info","text":"

    These fields are optional.

    # optional\nEnv = ''\n# optional\nAppID = ''\n# optional\nServer = []\n# optional\nGRPCAddress = ''\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#database","title":"Database","text":"

    To config [SpDB], [BsDB], you have to input the user name, db password,db address and db name in these fields.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#piecestore","title":"PieceStore","text":"

    To config [PieceStore] and [PieceStore.Store], you can read the details in this doc

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#chain-info","title":"Chain info","text":""},{"location":"bnb-greenfield/storage-provider/run-book/config/#spaccount","title":"SpAccount","text":"

    These private keys are generated during wallet setup.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#endpoint","title":"Endpoint","text":"

    [Endpoint] specified the URL of different services.

    For single-machine host (not recommended):

    [Endpoint]\nApproverEndpoint = ''\nManagerEndpoint = ''\nDownloaderEndpoint = ''\nReceiverEndpoint = ''\nMetadataEndpoint = ''\nUploaderEndpoint = ''\nP2PEndpoint = ''\nSignerEndpoint = ''\nAuthenticatorEndpoint = ''\n

    For K8S cluster:

    [Endpoint]\nApproverEndpoint = 'manager:9333'\nManagerEndpoint = 'manager:9333'\nDownloaderEndpoint = 'downloader:9333'\nReceiverEndpoint = 'receiver:9333'\nMetadataEndpoint = 'metadata:9333'\nUploaderEndpoint = 'uploader:9333'\nP2PEndpoint = 'p2p:9333'\nSignerEndpoint = 'signer:9333'\nAuthenticatorEndpoint = 'localhost:9333'\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#p2p","title":"P2P","text":"

    Note

    We don\u2019t use P2P service in mainnet and testnet, so users can ignore P2P items.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#gateway","title":"Gateway","text":"
    [Gateway]\nDomainName = 'region.sp-name.com'\n

    The correct configuration should not include the protocol prefix https://.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#blocksyncer","title":"BlockSyncer","text":"

    Here is block_syncer config. The configuration of BsDBWriteAddress can be the same as the BSDB.Address module here. To enhance performance, you can set up the write database address here and the corresponding read database address in BSDB.

    Modules = ['epoch','bucket','object','payment','group','permission','storage_provider','prefix_tree', 'virtual_group','sp_exit_events','object_id_map','general']\nWorkers = 50\nBsDBWriteAddress = 'localhost:3306'\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#fundingprivatekey","title":"FundingPrivateKey","text":"

    There is no need to write FundingPrivateKey in config.toml. It should be kept in cold wallet for safety.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#rcmgr","title":"Rcmgr","text":"

    ResourceManager manages resources within SP system, tracking and accounting for usage across the stack, from internal components to applications. It also allows for resource usage to be limited based on user-configurable policies. Config schema shows as below:

    message GfSpLimit {\n  int64 memory = 1;\n  int32 tasks = 2;\n  int32 tasks_high_priority = 3;\n  int32 tasks_medium_priority = 4;\n  int32 tasks_low_priority = 5;\n  int32 fd = 6;\n  int32 conns = 7;\n  int32 conns_inbound = 8;\n  int32 conns_outbound = 9;\n}\n\nmessage GfSpLimiter {\n  GfSpLimit system = 1;\n  GfSpLimit transient = 2;\n  map<string, GfSpLimit> service_limit = 3;\n}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#quota","title":"Quota","text":"

    Here is quota config. The configuration of MonthlyFreeQuota define the free quota in each month.It will be reduced when the charge quota is exhausted.

    [Quota]\nMonthlyFreeQuota = 0\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#sp-probe","title":"SP Probe","text":"

    It contains two probes: liveness and readiness probe. If users want to check SP whether is healthy and ready. Users can refer Kubernetes docs to learn related concepts. About detailed SP probe info, users can refer SP probe.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#sp-mainnet-recommended-config","title":"SP Mainnet Recommended Config","text":"

    This section shows the config of official in Greenfield, so users can add use similar config:

    # optional\nEnv = \"mainnet\"\n# optional\nServer = []\n# optional\nGRPCAddress = '0.0.0.0:9333'\n\n[SpDB]\n# required\nUser = ''\n# required\nPasswd = ''\n# required\nAddress = '{your_db_address}'\n# required\nDatabase = 'storage_provider_db'\n\n[BsDB]\n# required\nUser = ''\n# required\nPasswd = ''\n# required\nAddress = '{your_db_address}'\n# required\nDatabase = 'block_syncer'\n\n[PieceStore]\n# required\nShards = 0\n\n[PieceStore.Store]\n# required\nStorage = 's3'\n# optional\nBucketURL = '{your_bucker_url}'\n# optional\nMaxRetries = 5\n# optional\nMinRetryDelay = 0\n# optional\nTLSInsecureSkipVerify = false\n# required\nIAMType = 'SA'\n\n[Chain]\n# required\nChainID = 'greenfield_1017-1'\n# required\nChainAddress = ['{your_fullnode_address}']\n\n[SpAccount]\n# required\nSpOperatorAddress = '{your_operator_address}'\n# required\n# OperatorPrivateKey = ''\n# required\n# SealPrivateKey = ''\n# required\n# ApprovalPrivateKey = ''\n# required\n# GcPrivateKey = ''\n\n[Endpoint]\n# required\nApproverEndpoint = 'approver:9333'\n# required\nManagerEndpoint = 'manager:9333'\n# required\nDownloaderEndpoint = 'downloader:9333'\n# required\nReceiverEndpoint = 'receiver:9333'\n# required\nMetadataEndpoint = 'metadata:9333'\n# required\nUploaderEndpoint = 'uploader:9333'\n# required\nP2PEndpoint = 'p2p-service:9333'\n# required\nSignerEndpoint = 'signer:9333'\n# required\nAuthenticatorEndpoint = 'localhost:9333'\n\n[Gateway]\n# required\nDomainName = '{your_domain_name}'\n# required\nHTTPAddress = '0.0.0.0:9033'\n\n[P2P]\n# optional\n#P2PPrivateKey = ''\n# optional\nP2PAddress = '0.0.0.0:9933'\n# optional\nP2PAntAddress = ''\n# optional\nP2PBootstrap = []\n# optional\n# P2PPingPeriod = 0\n\n[Parallel]\n# optional\nDiscontinueBucketEnabled = false\n# optional\nDiscontinueBucketKeepAliveDays = 365\n# optional\nGlobalMaxUploadingParallel = 3072\n# optional\nUploadObjectParallelPerNode = 100\n# optional\nReceivePieceParallelPerNode = 1024\n# optional\nDownloadObjectParallelPerNode = 200\n# optional\nChallengePieceParallelPerNode = 200\n# optional\nAskReplicateApprovalParallelPerNode = 10240\n# optional\nGlobalCreateBucketApprovalParallel = 1024\n# optional\nGlobalCreateObjectApprovalParallel = 1024\n# optional\nGlobalUploadObjectParallel = 1024\n# optional\nGlobalReplicatePieceParallel = 1024\n# optional\nGlobalSealObjectParallel = 1024\n# optional\nGlobalReceiveObjectParallel = 10240\n# optional\nGlobalBackupTaskParallel = 1024\n# optional\nGlobalRecoveryPieceParallel = 1024\n# optional\nGlobalGcObjectSafeBlockDistance = 64\n# optional\nGlobalMigrateGVGParallel = 10\n\n[Monitor]\n# required\nDisableMetrics = false\n# required\nDisablePProf = false\n# required\nDisableProbe = false\n# required\nMetricsHTTPAddress = '0.0.0.0:24367'\n# required\nPProfHTTPAddress = '0.0.0.0:24368'\n# required\nProbeHTTPAddress = '0.0.0.0:24369'\n\n# optional\n[Rcmgr]\n# optional\nDisableRcmgr = false\n# optional\n[Rcmgr.GfSpLimiter]\n# optional\n[Rcmgr.GfSpLimiter.System]\n# optional\nMemory = 4294967296\n# optional\nTasks = 10240\n# optional\nTasksHighPriority = 128\n# optional\nTasksMediumPriority = 1024\n# optional\nTasksLowPriority = 16\n# optional\nFd = 2147483647\n# optional\nConns = 2147483647\n# optional\nConnsInbound = 2147483647\n# optional\nConnsOutbound = 2147483647\n\n[BlockSyncer]\n# required\nModules = ['epoch','bucket','object','payment','group','permission','storage_provider','prefix_tree','virtual_group','sp_exit_events','object_id_map','general']\n# required\nWorkers = 50\n# optional\nBsDBWriteAddress = \"{your_db_address}\"\n\n[APIRateLimiter]\n# every line should represent one entry of gateway route. The comment after each line must contain which route name it represents.\n# Most of APIs has a qps number, offered by QA team.  That usually means the max qps for the whole 4 gateway cluster.\n# How to setup the RateLimit value, it is a sophistcated question and need take a lot of factors into account.\n# 1. For most query-APIs, we can setup a rate limit up to the 1/4 of max qps, as the config is for only one gateway instance.\n# 2. Also we avoid to setup a too large or too small rate limit value.\n# 3. For upload/download APIs, it is diffiult to use a rate limit as a protect mechanism for the servers. Because the performance of upload/download interactions usually dependens on how large the file is processed.\n# 4. We tetatively setup 50~75 as the rate limit for the download/upload APIs and we can ajdust them once we have a better experience.\n# 5. Currently, please only put one name inside the name list of PathPatttern\n\n# optional\nPathPattern = [\n    {Key = \"/auth/request_nonce\", Method = \"GET\", Names = [\"GetRequestNonce\"]},\n    {Key = \"/auth/update_key\", Method = \"POST\", Names = [\"UpdateUserPublicKey\"]},\n    {Key = \"/permission/.+/[^/]*/.+\", Method = \"GET\", Names = [\"VerifyPermission\"]},\n    {Key = \"/greenfield/admin/v1/get-approval\", Method = \"GET\", Names = [\"GetApproval\"]},\n    {Key = \"/greenfield/admin/v1/challenge\", Method = \"GET\", Names = [\"GetChallengeInfo\"]},\n    {Key = \"/greenfield/admin/v2/challenge\", Method = \"GET\", Names = [\"GetChallengeInfo\"]},\n    {Key = \"/greenfield/receiver/v1/replicate-piece\", Method = \"PUT\", Names = [\"ReplicateObjectPiece\"]},\n    {Key = \"/greenfield/recovery/v1/get-piece\", Method = \"GET\", Names = [\"RecoveryPiece\"]},\n    {Key = \"/greenfield/migrate/v1/notify-migrate-swap-out-task\", Method = \"POST\", Names = [\"NotifyMigrateSwapOut\"]},\n    {Key = \"/greenfield/migrate/v1/migrate-piece\", Method = \"GET\", Names = [\"MigratePiece\"]},\n    {Key = \"/greenfield/migrate/v1/migration-bucket-approval\", Method = \"GET\", Names = [\"MigrationBucketApproval\"]},\n    {Key = \"/greenfield/migrate/v1/get-swap-out-approval\", Method = \"GET\", Names = [\"SwapOutApproval\"]},\n    {Key = \"/download/[^/]*/.+\", Method = \"GET\", Names = [\"DownloadObjectByUniversalEndpoint\"]},{Key = \"/download\", Method = \"GET\", Names = [\"DownloadObjectByUniversalEndpoint\"]},\n    {Key = \"/view/[^/]*/.+\", Method = \"GET\", Names = [\"ViewObjectByUniversalEndpoint\"]},{Key = \"/view\", Method = \"GET\", Names = [\"ViewObjectByUniversalEndpoint\"]},\n    {Key = \"/status\", Method = \"GET\", Names = [\"GetStatus\"]},\n    {Key = \"/.+/.+[?]offset.*\", Method = \"POST\", Names = [\"ResumablePutObject\"]},\n    {Key = \"/.+/.+[?]upload-context.*\", Method = \"GET\", Names = [\"QueryResumeOffset\"]},\n    {Key = \"/.+/.+[?]upload-progress.*\", Method = \"GET\", Names = [\"QueryUploadProgress\"]},\n    {Key = \"/.+/.+[?]bucket-meta.*\", Method = \"GET\", Names = [\"GetBucketMeta\"]},\n    {Key = \"/.+/.+[?]object-meta.*\", Method = \"GET\", Names = [\"GetObjectMeta\"]},\n    {Key = \"/.+/.+[?]object-policies.*\", Method = \"GET\", Names = [\"ListObjectPolicies\"]},\n    {Key = \"/.+[?]read-quota.*\", Method = \"GET\", Names = [\"GetBucketReadQuota\"]},\n    {Key = \"/.+[?]list-read-quota.*\", Method = \"GET\", Names = [\"ListBucketReadRecord\"]},\n    {Key = \"/[?].*group-query.*\", Method = \"GET\", Names = [\"GetGroupList\"]},\n    {Key = \"/[?].*objects-query.*\", Method = \"GET\", Names = [\"ListObjectsByIDs\"]},\n    {Key = \"/[?].*buckets-query.*\", Method = \"GET\", Names = [\"ListBucketsByIDs\"]},\n    {Key = \"/[?].*verify-id.*\", Method = \"GET\", Names = [\"VerifyPermissionByID\"]},\n    {Key = \"/[?].*user-groups.*\", Method = \"GET\", Names = [\"GetUserGroups\"]},\n    {Key = \"/[?].*group-members.*\", Method = \"GET\", Names = [\"GetGroupMembers\"]},\n    {Key = \"/[?].*owned-groups.*\", Method = \"GET\", Names = [\"GetUserOwnedGroups\"]},\n\n    {Key = \"/.+/$\", Method = \"GET\", Names = [\"ListObjectsByBucket\"]},\n    {Key = \"/.+/.+\", Method = \"GET\", Names = [\"GetObject\"]},\n    {Key = \"/.+/.+\", Method = \"PUT\", Names = [\"PutObject\"]},\n    {Key = \"/$\", Method = \"GET\", Names = [\"GetUserBuckets\"]},\n\n]\n\nNameToLimit = [\n    {Name = \"GetRequestNonce\", RateLimit = 100, RatePeriod = 'S'}, # requestNonceRouterName 3000qps\n    {Name = \"UpdateUserPublicKey\", RateLimit = 100, RatePeriod = 'S'}, # updateUserPublicKeyRouterName 4000qps\n    {Name = \"VerifyPermission\", RateLimit = 100, RatePeriod = 'S'}, # verifyPermissionRouterName  1200qps\n    {Name = \"GetApproval\", RateLimit = 35, RatePeriod = 'S'}, # approvalRouterName  150qps\n    {Name = \"GetChallengeInfo\", RateLimit = 20, RatePeriod = 'S'}, # getChallengeInfoRouterName, no test data\n    {Name = \"ReplicateObjectPiece\", RateLimit = 1000, RatePeriod = 'S'},  # replicateObjectPieceRouterName, no test data. Internal API among sps, no rate limit is needed.\n    {Name = \"RecoveryPiece\", RateLimit = 1000, RatePeriod = 'S'}, # recoveryPieceRouterName, no test data. Internal API among sps, no rate limit is needed.\n    {Name = \"NotifyMigrateSwapOut\", RateLimit = 10, RatePeriod = 'S'},  # notifyMigrateSwapOutRouterName, no test data. Internal API among sps, no rate limit is needed.\n    {Name = \"MigratePiece\", RateLimit = 10, RatePeriod = 'S'}, # migratePieceRouterName, no test data\n    {Name = \"MigrationBucketApproval\", RateLimit = 10, RatePeriod = 'S'}, # migrationBucketApprovalName, no test data\n    {Name = \"SwapOutApproval\", RateLimit = 10, RatePeriod = 'S'}, # swapOutApprovalName, no test data\n    {Name = \"DownloadObjectByUniversalEndpoint\", RateLimit = 50, RatePeriod = 'S'}, # downloadObjectByUniversalEndpointName, 50qps\n    {Name = \"ViewObjectByUniversalEndpoint\", RateLimit = 50, RatePeriod = 'S'}, # viewObjectByUniversalEndpointName, 50qps\n    {Name = \"GetStatus\", RateLimit = 200, RatePeriod = 'S'},# getStatusRouterName, 2000qps\n    {Name = \"ResumablePutObject\", RateLimit = 30, RatePeriod = 'S'}, # resumablePutObjectRouterName , test data is same as putObject object 10qps\n    {Name = \"QueryResumeOffset\", RateLimit = 30, RatePeriod = 'S'},  # queryResumeOffsetName, test data is same as putObject object 10qps\n    {Name = \"QueryUploadProgress\", RateLimit = 50, RatePeriod = 'S'}, # queryUploadProgressRouterName, test data is same as putObject object 10qps\n    {Name = \"GetBucketMeta\", RateLimit = 100, RatePeriod = 'S'}, # getBucketMetaRouterName, 400qps\n    {Name = \"GetObjectMeta\", RateLimit = 100, RatePeriod = 'S'}, # getObjectMetaRouterName, 400qps\n    {Name = \"ListObjectPolicies\", RateLimit = 200, RatePeriod = 'S'}, # listObjectPoliciesRouterName, 2000qps\n    {Name = \"GetBucketReadQuota\", RateLimit = 200, RatePeriod = 'S'}, # getBucketReadQuotaRouterName\n    {Name = \"ListBucketReadRecord\", RateLimit = 100, RatePeriod = 'S'}, # listBucketReadRecordRouterName\n    {Name = \"GetGroupList\", RateLimit = 200, RatePeriod = 'S'}, # getGroupListRouterName\uff0c similar to getUserGroupsRouterName, 2000qps\n    {Name = \"ListObjectsByIDs\", RateLimit = 200, RatePeriod = 'S'}, # listObjectsByIDsRouterName, 1200qps\n    {Name = \"ListBucketsByIDs\", RateLimit = 200, RatePeriod = 'S'}, # listBucketsByIDsRouterName, 2000qps\n    {Name = \"VerifyPermissionByID\", RateLimit = 200, RatePeriod = 'S'}, # verifyPermissionByIDRouterName, 1200qps\n    {Name = \"GetUserGroups\", RateLimit = 200, RatePeriod = 'S'}, # getUserGroupsRouterName, 2000qps\n    {Name = \"GetGroupMembers\", RateLimit = 200, RatePeriod = 'S'}, # getGroupMembersRouterName, 2000qps\n    {Name = \"GetUserOwnedGroups\", RateLimit = 200, RatePeriod = 'S'}, # getUserOwnedGroupsRouterName, 2000qps\n\n    {Name = \"ListObjectsByBucket\", RateLimit = 75, RatePeriod = 'S'}, # listObjectsByBucketRouterName, 300qps\n    {Name = \"GetObject\", RateLimit = 75, RatePeriod = 'S'}, # getObjectRouterName, 100 qps\n    {Name = \"PutObject\", RateLimit = 75, RatePeriod = 'S'}, # putObjectRouterName, 100 qps\n    {Name = \"GetUserBuckets\", RateLimit = 75, RatePeriod = 'S'}] # getUserBucketsRouterName, 1000 qps\n\nHostPattern = []\n\n[Manager]\n# optional\nEnableLoadTask = true\n# optional\nGVGPreferSPList = [1,2,3,4,5,6,7]\n# optional\nEnableTaskRetryScheduler = true\n\n[Executor]\n# optional\nListenSealRetryTimeout = 30\n\n[Quota]\nMonthlyFreeQuota = 0\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/","title":"Exit Greenfield SP Network - BNB Greenfield SP","text":"

    This guide provides step-by-step instructions for SPs to exit the Greenfield NextWork on the Mainnet or Testnet, along with the necessary actions to be performed by both the exiting SP and the successor SP(s).

    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#how-to-exit-greenfield-network","title":"How to exit Greenfield network","text":"

    When an SP decides to exit the Greenfield network, there are three main steps to go through, involving both the exiting SP and other SPs in the network:

    1. Declare the exit
    2. Data recovery by successor SP(s)
    3. Finalize the exit
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#1-declare-the-exit","title":"1. Declare the exit","text":"

    The exiting SP needs to initiate an StorageProviderExit transaction to Greenfield blockchain, which will turn its status to STATUS_GRACEFUL_EXITING.

    To exit the network, you can use the following commands based on the desired network:

    MainnetTestnet
    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\nchainId = \"greenfield_1017-1\"\n
    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\nchainId = \"greenfield_5600-1\"\n

    Command for storage provider to exit:

    gnfd-sp spExit [command options] [arguments...]\n
    Example:
    ./build/bin/gnfd-sp spExit --config ./config.toml\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#2-data-recovery","title":"2. Data recovery","text":"

    For SPs interested in becoming successors, you need to perform the following data recovery steps:

    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#21-reserveswapin","title":"2.1 ReserveSwapIn","text":"

    The perspective successor SP needs to determine Global Virtual group(GVG) and Global Virtual Group Family(VGF) that exiting SP has, This information can be obtained from GreenfieldScan or by using the provided CLI.

    Usage:

    # List the GVG that the exit SP act as secondary SP\n./gnfd-sp query-gvg-by-sp [command options] [arguments...]\n# List the GVG Family that the exit SP act as primary SP\n./gnfd-sp query-vgf-by-sp [command options] [arguments...]\n
    Example:
    # List the GVG that the exit SP(id=1) act as secondary SP\n./gnfd-sp query-gvg-by-sp --config ./config.toml -sp 1\n# List the GVG Family that the exit SPP(id=1) act as primary SP\n./gnfd-sp query-vgf-by-sp --config ./config.toml -sp 1\n

    Once the successor SP has obtained the necessary information, it needs to reserve the position in the exit SP\u2019s GVG Family or GVG.

    Usage:

    # Reserve the exit SP's position in GVG family or GVG\n./gnfd-sp swapIn [command options] [arguments...]\n

    Example:

    # Reserve the exit SP's(id=1) position in GVG family(id=1)\n./gnfd-sp swapIn --config ./config.toml -f 1 -sp 1\n# Reserve the exit SP's(id=1) position in GVG(id=1)\n./gnfd-sp swapIn --config ./config.toml --gid 1 -sp 1\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#22-data-recovery","title":"2.2 Data Recovery","text":"

    The data recovery process is triggered by the successor SP using the following commands:

    Usage:

    ./gnfd-sp recover-vgf [command options] [arguments...]\n./gnfd-sp recover-gvg [command options] [arguments...]\n
    Example:
    # To recover the exit SP's data in the VGF(id=1) as a primary SP:\n./gnfd-sp recover-vgf --config /config/config.toml -f 1\n# To recover the exit SP's data in the GVG(id=1) as a secondary SP:\n./gnfd-sp swapIn --config ./config.toml --gid 1\n
    Once the recovery job is triggered, it will run in the background in the SP Manager module. The progress can be queried using the following command:

    Usage:

    ./gnfd-sp query-recover-p [command options] [arguments...]\n
    Example:
    # Query the GVG family(id=1) recover progress \n./gnfd-sp recover-vgf --config /config/config.toml -f 1\n# Query the GVG(id=1) recover progress\n./gnfd-sp recover-vgf --config /config/config.toml --gid 1\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#23-completeswapin","title":"2.3 CompleteSwapIn","text":"

    Upon completion of the data recovery process and successful verification, the successor SP needs to send a CompleteSwapIn transaction to the Greenfield blockchain, it will be automatically conducted before the recover process concludes, This will finalize the recovery process and allow the successor SP to take over the position in the GVG Family or GVG.

    Note

    It is crucial to note that under no circumstances should the CompleteSwapIn be triggered manually if the successor SP has not completed the data recovery process but acknowledges it. Doing so may result in data availability challenges and potential loss of funds.

    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#3-finalize-the-exit","title":"3. Finalize the Exit","text":"

    Once the successor SP has completed the data recovery process and taken over the position in the GVG Family or GVG, by checking the GVG statistic of exitting SP, confirm that there are no more GVGs associated with it. Anyone in Greenfield network can send a CompleteStorageProviderExit transaction to the Greenfield blockchain to finalize its exit from the network. Below shows the CLI triggered by exiting SP itself.

    Usage:

    ./gnfd-sp completeSpExit [command options] [arguments...]\n

    Example:

    ./gnfd-sp completeSpExit --config /config/config.toml\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/","title":"Join SP Network - BNB Greenfield SP","text":"

    This guide will help you join SP Network: Mainnet and Testnet.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#prerequisite-for-becoming-a-mainnet-sp","title":"Prerequisite for Becoming a Mainnet SP","text":"

    To ensure the stable provision of data services, Storage Providers must meet specific criteria to join the mainnet. - The SP must join the testnet for a minimum of one month. - The SP must store over 1K files across more than 100 buckets on the testnet. - There were no slash event on the SP in the past week.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#how-to-join-sp-network","title":"How to Join SP Network?","text":"

    Greenfield Blockchain validators are responsible for selecting storage providers. For each on-chain proposal to add new storage provider, there are deposit period for depositing BNB and voting period for validators to make votes. Once the proposal passes, new SP can join the network afterwards.

    You can query the governance parameters here.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#1-submit-proposal","title":"1. Submit Proposal","text":"

    The SP needs to initiate an on-chain proposal that specifies the Msg information to be automatically executed after the vote is approved. In this case, the Msg is MsgCreateStorageProvider. It\u2019s worth noting that the deposit tokens needs to be greater than the minimum deposit tokens specified on the chain.

    MainnetTestnet
    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\nchainId = \"greenfield_1017-1\"\n
    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\nchainId = \"greenfield_5600-1\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#hot-wallet-manual","title":"Hot Wallet Manual","text":"

    You can use the gnfd command to directly send the transaction for creating a storage provider. To do this, please import the private key of the funding account into the Keystore.

    However, it is not safe to use a hot wallet for Mainnet. Instead, you should refer to the Hardware Wallet Manual for instructions on using a hardware wallet.

    Command for creating storage provider:

    ./build/bin/gnfd tx sp create-storage-provider ./create_storage_provider.json --from {funding_address} --node ${rpcAddr} --chain-id ${chainId} --keyring-backend os\n

    The content for create_storage_provider.json, modify it with the correct values as you need:

    cat ./create_storage_provider.json\n{\n  \"messages\":[\n  {\n    \"@type\":\"/greenfield.sp.MsgCreateStorageProvider\",\n    \"description\":{\n      \"moniker\":\"{moniker}\",\n      \"identity\":\"{identity}\",\n      \"website\":\"{website}\",\n      \"security_contact\":\"{security_contract}\",\n      \"details\":\"{details}\"\n    },\n    \"sp_address\":\"{operator_address}\",\n    \"funding_address\":\"{funding_address}\",\n    \"seal_address\":\"{seal_address}\",\n    \"approval_address\":\"{approval_address}\",\n    \"gc_address\":\"{gc_address}\",\n    \"maintenance_address\":\"{maintenance__address}\",\n    \"endpoint\":\"https://{your_endpoint}\",\n    \"deposit\":{\n      \"denom\":\"BNB\",\n      # Mainnet: 500000000000000000000, Testnet: 1000000000000000000000\n      \"amount\":\"500000000000000000000\"\n    },\n    \"read_price\":\"0.1469890427\",\n    \"store_price\":\"0.02183945725\",\n    \"free_read_quota\": 1073741824,\n    \"creator\":\"0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2\",\n    \"bls_key\":\"{bls_pub_key}\",\n    \"bls_proof\":\"{bls_proof}\"\n  }\n],\n  \"metadata\":\"4pIMOgIGx1vZGU=\",\n  \"title\":\"Create <name> Storage Provider\",\n  \"summary\":\"create <name> Storage Provider\",\n  \"deposit\":\"1000000000000000000BNB\"\n}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#hardware-wallet-manual","title":"Hardware Wallet Manual","text":"

    The gnfd command is not available for connecting with the hardware wallet, so you should use the gnfd-tx-sender to send transactions. Here are the steps:

    1. Generate the transaction data.
      ./build/bin/gnfd tx sp create-storage-provider ./create_storage_provider.json --from {funding_address} --print-eip712-msg-type\n
    2. Visit the gnfd-tx-sender website.
    3. Add your hardware wallet into Metamask, and connect the wallet.
    4. Navigate to the Custom Tx page and fill in the generated transaction data in step1.
    5. Click the Submit button to send the transaction.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#understanding-the-parameters","title":"Understanding the Parameters","text":"

    Note

    You can get the gov module address by this command

    curl -X GET \"https://greenfield-chain-us.bnbchain.org/cosmos/auth/v1beta1/module_accounts/gov\" -H  \"accept: application/json\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#2-deposit-bnb-to-proposal","title":"2. Deposit BNB to Proposal","text":"

    Note

    You can get the mininum deposit for proposal by the above command. Please make sure that the initial deposit is greater than min_deposit when submitting the proposal.

    curl -X GET \"https://greenfield-chain-us.bnbchain.org/cosmos/gov/v1/params/deposit\" -H  \"accept: application/json\"\n

    You can skip this step if the initial deposit amount is greater than the min deposit required by the proposal.

    Each proposal needs to deposit enough tokens to enter the voting phase.

    ./build/bin/gnfd tx gov deposit ${proposal_id} 1BNB --from ${funding_address} --keyring-backend os --node ${rpcAddr} --chain-id ${chainId}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#3-wait-voting-and-check-voting-result","title":"3. Wait Voting and Check Voting Result","text":"

    After submitting the proposal successfully, you must wait for the voting to be completed and the proposal to be approved. It will last 7 days on Mainnet while 1 day on Testnet. Once it has passed and is executed successfully, you can verify that the storage provider has been joined.

    Warning

    Please ensure that the storage provider service is running before it has been joined.

    You can check the on-chain SP information to confirm whether the SP has been successfully created.

    ./build/bin/gnfd query sp storage-providers --node ${rpcAddr}\n

    Alternatively, you can check the proposal to know about its execution status.

    ./build/bin/gnfd query gov proposal ${proposal_id} --node ${rpcAddr}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#4-activate-sp","title":"4. Activate SP","text":""},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#storage-provider-standard-test","title":"Storage Provider Standard Test","text":"

    After the proposal has passed, the status of SP is STATUS_IN_MAINTENANCE. To prevent being slashed due to functional abnormalities, you should first perform a full functional test using the maintenance account. You can refer to the SP standard test.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#update-sp-status","title":"Update SP status","text":"

    Once the testing is completed, you need to send a tx to activate the SP to STATUS_IN_SERVICE.

    gnfd tx sp update-status [sp-address] STATUS_IN_SERVICE [flags]\n

    Refer to Maintenance Mode for more details.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#5-sp-address-deposit","title":"5. SP address deposit","text":""},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#funding-address","title":"Funding Address","text":"

    As a new SP, you need deposit a minimum amount of BNB into the funding address. Please note the initial deposit requirement varies on different environments. You can check the sp.params.min_deposit value (in wei BNB) from genesis endpoint response of Greenfield testnet/mainnet. By the time when this doc is written,

    In addition, to join the network in Step 2, an SP must initiate a proposal using a funding address and stake 1 BNB to enter the voting phase. After the voting concludes, the 1 BNB will be refunded to the original account. Therefore, it is advisable for the Funding Address to reserve an additional >1 BNB to cover these costs.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#operator-address","title":"Operator Address","text":"

    SP operator address will be used to send \u201cCreate Global Virtual Group\u201d, \u201cEdit Storage Provider\u201d, \u201cUpdate Storage Provider Status\u201d and other txs to greenfield chain. So it requires some BNB deposited for transaction fee as well. We recommend SP operator address can hold at least 0.1 BNB but not necessarily as much as possible.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#storage-provider-operations","title":"Storage Provider Operations","text":""},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#editstorageprovider","title":"EditStorageProvider","text":"

    This command is used to edit the information of the SP, including endpoint, description, etc.

    Usage:

    gnfd tx sp edit-storage-provider [sp-address] [flags]\n

    For example, edit the endpoint:

    ./build/bin/gnfd tx sp edit-storage-provider ${operator_address} --endpoint ${new_endpoint} --from ${operator_address} --keyring-backend os --node ${rpcAddr} --chain-id ${chainId}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#update-sp-price","title":"Update SP Price","text":"

    Update the storage provider read, store price and free read quota, if there is no change to a specific value, the current value should also be provided.

    The unit of price is a decimal, which indicates wei BNB per byte per second. E.g. the price is 0.02183945725, means approximately $0.018 / GB / Month. (0.02183945725 * (30 * 86400) * (1024 * 1024 * 1024) * 300 / 10 ** 18 \u2248 0.018, assume the BNB price is 300 USD)

    The free-read-quota unit is bytes, for 1GB free quota, it should be 1073741824.

    Usage:

    gnfd tx sp update-price [sp-address] [read-price] [store-price] [free-read-quota] [flags]\n

    Example:

    ./build/bin/gnfd tx sp update-price ${operator_address} 0.1469890427 0.02183945725 1073741824 --from ${operator_address} --keyring-backend os ---node ${rpcAddr} --chain-id ${chainId}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#update-sp-quota","title":"Update SP Quota","text":"

    Besides the above update-price command, you can also use the gnfd-sp command to update the free read quota for SP. The update.quota command is used to update the free quota of the SP, it will send a transaction to the blockchain to update the free read quota, but keep the storage price and read price unchanged.

    Usage:

    gnfd-sp update.quota [command options] [arguments...]\n

    Example:

    ./build/bin/gnfd-sp update.quota --quota 1073741824 --config ./config.toml\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#recover-sp-objects","title":"Recover SP Objects","text":"

    Besides the above commands, you can also use the gnfd-sp command to recover objects for SP, whether it is the primary or secondary sp of the object. The recover.object command is used to recover an object or objects of the SP, it will send a request to other SPs to get replicate of the object(s) you want to recover.

    Usage:

    gnfd-sp recover.object [command options] [arguments...]\n

    Example:

    ./build/bin/gnfd-sp recover.object --config ./config.toml -b bucket_name -o single_object_name\n./build/bin/gnfd-sp recover.object --config ./config.toml -b bucket_name -l object_name1//_object_name2//object_name3\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#claim-sp-income","title":"Claim SP Income","text":"

    To claim income, a storage provider can use settle cmd to settle income in global virtual group families or global virtual groups. To find the global virtual group families or global virtual groups to settle, a storage provider can use query.primary.sp.income or query.secondary.sp.income of gnfd-sp commands.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#to-query-the-income-of-a-primary-sp","title":"To query the income of a primary sp","text":"

    Usage:

    # query sp's income in global virtual group families\ngnfd-sp query.primary.sp.income --config config.toml --sp.id ${sp_id}\n

    An example of response will look like:

    querying primary sp income details for sp  1\nquery timestamp 1698830787 2023-11-01 17:26:27 +0800 CST\nquery results: [{\"vgf_id\":2,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_1\",\"crud_timestamp\":1698631653,\"netflow_rate\":\"4643666191\",\"static_balance\":\"1093710972008743\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"2018422795287337\"},{\"vgf_id\":13,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_2\",\"crud_timestamp\":1698745565,\"netflow_rate\":\"5452639431\",\"static_balance\":\"38607334626064242\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"39072019463652924\"},{\"vgf_id\":15,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_3\",\"crud_timestamp\":1698573876,\"netflow_rate\":\"1925652979\",\"static_balance\":\"55285141693450020\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"55779863125937889\"},{\"vgf_id\":23,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_4\",\"crud_timestamp\":1698745588,\"netflow_rate\":\"5063874897\",\"static_balance\":\"2339430126330703\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"2770867203680206\"},{\"vgf_id\":246,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_5\",\"crud_timestamp\":1698667216,\"netflow_rate\":\"59568181\",\"static_balance\":\"19326420423320\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"29070047357671\"}]\n

    The unit of the unsettled income is wei BNB. The first element in above query result array means the sp 1 gets 2018422795287337 wei BNB in vgf_id 2.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#to-query-the-income-of-a-secondary-sp","title":"To query the income of a secondary sp","text":"
    # query sp's income in global virtual groups\ngnfd-sp query.secondary.sp.income --config config.toml --sp.id ${sp_id}\n

    An exmaple of response will look like:

    querying secondary sp income details for sp  1\nquery timestamp 1698830440 2023-11-01 17:20:40 +0800 CST\nquery results: [{\"gvg_id\":2531,\"stream_record\":{\"account\":\"secondary_sp_virtual_payment_account_address_1\",\"crud_timestamp\":1695347375,\"netflow_rate\":\"22256589564\",\"static_balance\":\"917684637479280\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"13073138794535490\"},{\"gvg_id\":8,\"stream_record\":{\"account\":\"secondary_sp_virtual_payment_account_address_2\",\"crud_timestamp\":1696735440,\"netflow_rate\":\"6698761332\",\"static_balance\":\"24312367733445348\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"6391045453997558\"},{\"gvg_id\":11,\"stream_record\":{\"account\":\"secondary_sp_virtual_payment_account_address_3\",\"crud_timestamp\":1696072153,\"netflow_rate\":\"6832159830\",\"static_balance\":\"15803326565544654\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"5774730701092644\"}\n    ...\n]\n
    The unit of the unsettled income is wei BNB. The first element in above query result array means the sp 1 gets 13073138794535490 wei BNB in gvg_id 2531.
    # settle income in global virtual group family or global virtual groups\ngnfd tx virtualgroup settle [global-virtual-group-family-id] [global-virtual-group-ids] [flags]\n

    Example:

    # query sp's income in global virtual group families\ngnfd-sp query.primary.sp.income --config config.toml --sp.id 1\n
    # query sp's income in global virtual groups\ngnfd-sp query.secondary.sp.income --config config.toml --sp.id 2\n
    # settle income in global virtual group family with id 100\ngnfd tx virtualgroup settle 100 0 [flags]\n\n# settle income in global virtual groups with id 2 or 3 or 4\ngnfd tx virtualgroup settle 0 2,3,4 [flags]\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#tools","title":"Tools","text":"

    SP can use Greenfield Cmd or DCellar to verify its functions:

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#trouble-shooting","title":"Trouble Shooting","text":"

    If you meet issues, please refer to SP common issues.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/","title":"Deploy Piece Store - BNB Greenfield SP","text":"

    Greenfield SP is a storage infrastructure for Greenfield decentralized storgage platform. Greenfield SP uses PieceStore to store users\u2019 payload data.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#piecestore-config","title":"PieceStore Config","text":"

    When creating a PieceStore, there are the following options to configure underlying storage:

    [PieceStore]\n# required\nShards = 0\n\n[PieceStore.Store]\n# required\nStorage = ''\n# optional\nBucketURL = ''\n# optional\nMaxRetries = 0\n# optional\nMinRetryDelay = 0\n# optional\nTLSInsecureSkipVerify = false\n# required\nIAMType = ''\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#shards","title":"Shards","text":"

    When creating a PieceStore, multiple buckets can be defined as the underlying storgae through the Shards option. Based on the sharding, SP can distribute the files to multiple buckets according to the hashed value of the file name. Data sharding technology can distribute the load of concurrent writing of large-scale data to multiple buckets, thereby improving the writing performance.

    The following are points to note when using the data sharding function:

    For example, the following config creates PieceStore with 5 shards.

    [PieceStore]\nShards = 5\n\n[PieceStore.Store]\nStorage = 'minio'\nBucketURL = 'http://10.180.42.161:9000/mybucket%d'\nIAMType = 'AKSK'\n

    After SP initialized through the above command, PieceStore will create 5 buckets named mybucket0, mybucket1, mybucket2, mybucket3 and mybucket4.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#iamtype","title":"IAMType","text":"

    PieceStore supports two authentication modes: AKSK and SA.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#aksk","title":"AKSK","text":"

    In AKSK mode, PieceStore will access object storage by using AccessKeyID and AccessKeySecret. If users use s3 as object storage, you can set AWSAccessKey and AWS_SECRET_KEY into environment variables which are more secure.

    Permanent access credentials generally have two parts, Access Key, Secret Key, while temporary access credentials generally include three parts, Access Key, Secret Key and token, and temporary access credentials have an expiration time, usually between a few minutes and a few hours.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#sa","title":"SA","text":"

    Service Account (abbreviated as SA) is a more secure way for object storage system to authenticate users. In this mode, you needn\u2019t to provide AccessKeyID and AccessKeySecret. If you deploy your SP in Kubernetes, we recommend you using SA to access object storage. AWS S3 can read this documentation to learn how to use SA. Alibaba Cloud OSS uses OIDC to visit OSS safely which users don\u2019t need to provide AccessKeyID and AccessKeySecret.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#how-to-get-temporary-credentials","title":"How to get temporary credentials","text":"

    Different cloud vendors have different acquisition methods. Generally, the Access Key, Secret Key and ARN representing the permission boundary of the temporary access credential are required as parameters to request access to the STS server of the cloud service vendor to obtain the temporary access credential. This process can generally be simplified by the SDK provided by the cloud vendor. For example, Amazon S3 can refer to this link to obtain temporary credentials, and Alibaba Cloud OSS can refer to this link.

    Temporary credentials are also set into environment variables such as s3 by AWS_SESSION_TOKEN, minio by MINIO_SESSION_TOKEN and so on. Due to there is an expiration time in temporary credentials, this is used in test mode.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#supported-storage-type","title":"Supported Storage Type","text":"

    PieceStore now supports the following storage system. If the listed storage systems don\u2019t conatin that you want to use, feel free to submit a requirement issue.

    Name value Amazon S3 s3 Alibaba Cloud OSS oss Backblaze B2 b2 MinIO minio File file Memory memory"},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#amazon-s3","title":"Amazon S3","text":"

    S3 supports two styles of endpoint URI: virtual hosted-style and path-style. The differences are:

    The <region> should be replaced with specific region code, e.g. the region code of US East (N. Virginia) is us-east-1. All the available region codes can be found here. If you use s3 as the underlying storage, you can set Storage = s3 in config.toml.

    AWS S3 AKSK environment variables as follows:

    // AWS_ACCESS_KEY defines env variable name for aws access key\nexport AWS_ACCESS_KEY=\"your_access_key\"\n// AWS_SECRET_KEY defines env variable name for aws secret key\nexport AWS_SECRET_KEY=\"your_secret_key\"\n// AWS_SESSION_TOKEN defines env variable name for aws session token, this is optional\nexport AWS_SESSION_TOKEN=\"your_session_token\"\n

    AWS S3 SA environment variables as follows:

    // AWS_ROLE_ARN defines env variable for aws role arnv\nexport AWS_ROLE_ARN=\"your_role_arn\"\n// AWSSecretKey defines env variable name for aws web identity token file\nexport AWS_WEB_IDENTITY_TOKEN_FILE=\"your_web_identity_token_file\"\n

    Note

    If the S3 bucket has public access (anonymous access is supported), please set export AWS_ACCESS_KEY=\"NoSignRequest\".

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#alibaba-cloud-oss","title":"Alibaba Cloud OSS","text":"

    Please follow this document to learn how to get access key and secret key. Alibaba Cloud also supports using Security Token Service (STS) to authorize temporary access to OSS. If you use OSS as the underlying storage, you can set Storage = oss in config.toml.

    Alibaba Cloud OSS AKSK environment variables as follows:

    // ALIBABA_CLOUD_ACCESS_KEY defines env variable name for OSS access key\nexport ALIBABA_CLOUD_ACCESS_KEY=\"your_access_key\"\n// ALIBABA_CLOUD_SECRET_KEY defines env variable name for OSS secret key\nexport ALIBABA_CLOUD_SECRET_KEY=\"your_secret_key\"\n// ALIBABA_CLOUD_SESSION_TOKEN defines env variable name for OSS session token, this is optional\nexport ALIBABA_CLOUD_SESSION_TOKEN=\"your_session_token\"\n// ALIBABA_CLOUD_OSS_REGION defines env variable name for OSS region\nexport ALIBABA_CLOUD_OSS_REGION=\"oss_region\"\n

    Alibaba Cloud OSS SA environment variables as follows:

    // ALIBABA_CLOUD_ROLE_ARN defines env variable for OSS role arnv\nexport ALIBABA_CLOUD_ROLE_ARN=\"your_role_arn\"\n// ALIBABA_CLOUD_OIDC_TOKEN_FILE defines env variable name for OSS oidc token file\nexport ALIBABA_CLOUD_OIDC_TOKEN_FILE=\"your_oidc_token_file\"\n// ALIBABA_CLOUD_OIDC_PROVIDER_ARN defines env variable for OSS oidc provider arn\nexport ALIBABA_CLOUD_OIDC_PROVIDER_ARN=\"your_oidc_provider_arn\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#backblaze-b2","title":"Backblaze B2","text":"

    To use Backblaze B2 as a storage system for Greenfield SP, you need to create application key firstly. Application Key ID and Application Key respectively corresponds to Access Key and Secret Key. If you use Backblaze B2 as the underlying storage, you can set Storage = b2 in config.toml.

    Backblaze B2 AKSK environment variables as follows:

    // B2_ACCESS_KEY defines env variable name for b2 access key\nexport B2_ACCESS_KEY=\"your_access_key\"\n// B2_SECRET_KEY defines env variable name for b2 secret key\nexport B2_SECRET_KEY=\"your_secret_key\"\n// B2_SESSION_TOKEN defines env variable name for b2 session token\nexport B2_SESSION_TOKEN=\"your_session_token\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#minio","title":"MinIO","text":"

    MinIO is a high-performance, S3 compatible object store. You can visit the official website to learn how to deploy and maintain a MinIO cluster or you can purchase minio service. If you use MinIO as the underlying storage, you can set Storage = minio in config.toml.

    MinIO AKSK environment variables as follows:

    // MINIO_REGION defines env variable name for minio region\nexport MINIO_REGION=\"minio_region\"\n// MINIO_ACCESS_KEY defines env variable name for minio access key\nexport MINIO_ACCESS_KEY=\"your_access_key\"\n// MINIO_SECRET_KEY defines env variable name for minio secret key\nexport MINIO_SECRET_KEY=\"your_secret_key\"\n// MINIO_SESSION_TOKEN defines env variable name for minio session token, this is optional\nexport MINIO_SESSION_TOKEN=\"your_session_token\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#file","title":"File","text":"

    When running Greenfield SP in your local machine, you can use local disk to test SP basic functions. The default storage path for root user is /var/piecestore and ~/.piecestore/local for ordinary users in Linux and macOS. In Windows system, the default path is C:/piecestore/local.

    Local storage is usually only used to help users understand how Greenfield SP works and to give users an experience on the basic features of Greenfield SP. The created PieceStore storage can only be used on a single machine. This is not recommended in production environment.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#memory","title":"Memory","text":"

    Memory type can be used to test all PieceStore interfaces in memory. It\u2019s convenient for unit test or e2e test.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/","title":"Run SP Node - BNB Greenfield SP","text":"

    This guide helps you set up an SP Node. Once you set up the SP Node successfully, you can follow the Join SP Network guide to make it online.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#prerequisites","title":"Prerequisites","text":""},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#recommended-hardware","title":"Recommended Hardware","text":"

    The following lists the recommended hardware requirements:

    IMPORTANT

    Each storage provider will hold 7 different accounts serving different purposes

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#wallet-preparation","title":"Wallet Preparation","text":"

    There are six accounts below, you can use the below command to generate these accounts:

    ./build/bin/gnfd keys add operator --keyring-backend os\n./build/bin/gnfd keys add seal --keyring-backend os\n./build/bin/gnfd keys add approval --keyring-backend os\n./build/bin/gnfd keys add gc --keyring-backend os\n./build/bin/gnfd keys add maintenance --keyring-backend os\n./build/bin/gnfd keys add bls --keyring-backend os --algo eth_bls\n

    and then export these private keys to prepare for SP deployment:

    ./build/bin/gnfd keys export operator --unarmored-hex --unsafe  --keyring-backend os\n./build/bin/gnfd keys export seal --unarmored-hex --unsafe --keyring-backend os\n./build/bin/gnfd keys export approval --unarmored-hex --unsafe --keyring-backend os\n./build/bin/gnfd keys export gc --unarmored-hex --unsafe --keyring-backend os\n./build/bin/gnfd keys export bls --unarmored-hex --unsafe --keyring-backend os\n

    IMPORTANT

    FundingAddress is used to deposit staking tokens and receive earnings. Therefore, users should prepare your own FundingAddress public key and private key. And keep private key of FundingAddress in cold wallet for safety!

    The private keys of OperatorAddress, SealAddress, ApprovalAddress, GCAddress and BlsAddress can be kept in hot wallet, because they are often used to send transactions.

    If you want to generate public key and private key of FundingAddress in gnfd binary file, you can execute the following commands:

    ./build/bin/gnfd keys add funding --keyring-backend os\n./build/bin/gnfd keys export funding --unarmored-hex --unsafe  --keyring-backend os\n

    maintenance account is not needed for SP deployment, but you should export it to conduct self-test:

    ./build/bin/gnfd keys export maintenance --unarmored-hex --unsafe --keyring-backend os\n

    Please keep these seven private keys safe!

    Moreover, obtain bls public key and generate bls proof to fill in the proposal of creating Storage Provider

    bls_pub_key:

    ./build/bin/gnfd keys show bls --keyring-backend os --output json | jq -r '.pubkey_hex' \n

    bls_proof:

    # Replace the ${bls_pub_key} with the above bls_pub_key to ensure sign the correct bls pub key!!!\n./build/bin/gnfd keys sign \"${bls_pub_key}\" --from bls --keyring-backend os\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#database-configuration","title":"Database Configuration","text":"

    You should create two databases: ${SpDB.Database} and ${BsDB.Database}. Both values can be found in configuration file.

    IMPORTANT

    ${BsDB.Database} requires the utf8mb4_unicode_ci as the character set and collation.

    The following example assumes ${SpDB.Database} as storage_provider_db and ${BsDB.Database} as block_syncer.

    # login in mysql and create database\n# the default encoding for the database should be utf8mb4_unicode_ci\nmysql> CREATE DATABASE storage_provider_db;\nmysql> CREATE DATABASE block_syncer CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n# check the database encoding format\nmysql> show create database block_syncer;\n

    This is the encoding we expect to see

    Database Create Database block_syncer CREATE DATABASE block_syncer /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */"},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#piecestore-configuration","title":"PieceStore Configuration","text":"

    Please follow this doc to config your PieceStore.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#gateway-configuration","title":"Gateway Configuration","text":""},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#1-support-both-path-style-and-virtual-style-routers-in-https-certificates","title":"1. Support both path-style and virtual-style routers in https certificates","text":"

    You need certificates for SP\u2019s exposed gateway service domain name and wildcard subdomain name of it, say you exposed your SP\u2019s gateway service on https://my-sp1.mainnet.dummy-sp.io, then you need SSL certificates for both my-sp1.mainnet.dummy-sp.io and *.my-sp1.mainnet.dummy-sp.io. For instance, if you reqeust AWS ACM certificate, you could request with this:

    Also, route all traffic from both my-sp1.mainnet.dummy-sp.io and *.my-sp1.mainnet.dummy-sp.io to gateway service, for instance, if you use nginx for ingress control, then you\u2019ll need to configure rules look like the following:

    rules:\n  - host: my-sp1.mainnet.dummy-sp.io\n    http:\n      paths:\n        - backend:\n            service:\n              name: gateway # where your SP gateway service is internally, such a k8s service.\n              port:\n                number: 9033\n          path: /\n          pathType: ImplementationSpecific\n  - host: '*.my-sp1.mainnet.dummy-sp.io'\n    http:\n      paths:\n        - backend:\n            service:\n              name: gateway # the same with the above one.\n              port:\n                number: 9033\n          path: /\n          pathType: ImplementationSpecific\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#2-cors-configuration","title":"2. CORS Configuration","text":"

    When working with web applications (e.g. DCellar), SPs need to allow CORS (Cross-Origin Resource Sharing) requests. See: CORS Errors

    If CORS is not configured properly, you may find the DCellar (or any other web applications which mean to interact with your SP) will report CORS errors, similar to below:

    Most people run their SP services behind the nginx or other similar reverse proxies. Usually the CORS settings should be configured in those reverse proxies.

    We recommend SP with reverse proxy can return the following headers:

    access-control-allow-headers: *\naccess-control-allow-methods: *\naccess-control-allow-origin: *\naccess-control-expose-headers: *\n

    After you finish the configuration, you can verify if it works in DCellar.

    1. Go to https://dcellar.io
    2. Press F12 to launch web developer tools and go to \u201cNetwork\u201d tab.
    3. Connect your wallet
    4. Find the \u201cOPTIONS\u201d request to your SP and check its status and response headers. If you see a similar result to the following screenshot, it means your CORS configuration is correct.
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#3-sample-cors-configuration-for-nginx","title":"3. Sample CORS Configuration for Nginx","text":"

    Many storage providers (SPs) prefer to use nginx as their SP\u2019s reverse proxy server. It can also help handle CORS requests.

    Below is a sample nginx config, which can return those expected http response headers about CORS, mentioned in above section. Please note that the nginx servers should explicitly return 204 as response code for http OPTIONS requests.

    server {\n    listen 443;\n    server_name example.com;\n\n    # Cors Preflight methods needs additional options and different Return Code\n    location / {\n        if ($request_method = 'OPTIONS') {\n            add_header 'Access-Control-Allow-Origin' '*';\n            add_header 'Access-Control-Allow-Methods' '*';\n            add_header 'Access-Control-Allow-Headers' '*';\n            add_header 'Access-Control-Max-Age' 1728000;\n            add_header 'Access-Control-Expose-Headers' '*';\n            add_header 'Content-Type' 'text/plain; charset=utf-8';\n            add_header 'Content-Length' 0;\n            return 204;\n        }\n\n        add_header 'Access-Control-Allow-Origin' '*';\n        add_header 'Access-Control-Allow-Methods' '*';\n        add_header 'Access-Control-Allow-Headers' '*';\n        add_header 'Access-Control-Expose-Headers' '*';\n\n        # Rest of your server configuration...\n    }\n}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#4-other-qa-on-nginx-config","title":"4. Other Q&A on Nginx config","text":"

    We observed that some SPs use nginx as their reverse-proxy layer. In this section , we will list some known best practises on nginx config.

    If your nginx uses proxy_pass directive to pass a request to a proxied server (e.g. the SP gateway microservice), you need also use proxy_set_header to set the HOST header. Otherwise, the head of request passed to the SP gateway, will be parsed as 127.0.0.1. In this case, the SP gateway could not verify the signature of the user requests.

    location / {\n  proxy_pass http://127.0.0.1:9033\n  proxy_set_header Host $host;\n}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#create-storage-provider","title":"Create Storage Provider","text":""},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#1-compile-sp","title":"1. Compile SP","text":"

    Follow the Compile SP doc to compile the SP binary or you can download the binary from the Greenfield Storage Provider Release.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#2-sp-config","title":"2. SP Config","text":""},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#generate-config-template","title":"Generate config template","text":"
    cd greenfield-storage-provider/build\n\n# dump default configuration\n./gnfd-sp config.dump\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#write-config","title":"Write config","text":"

    You can learn about how to write your config.toml file here

    It\u2019s recommended to deploy Kubernetes cluster following this guide. The corresonding config file is here.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#3-run-sp","title":"3. Run SP","text":"
    # start sp\n./gnfd-sp --config ${config_file_path}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/","title":"Run Local SP Network - BNB Greenfield SP","text":"

    This guide helps you to set up a local Greenfield Storage Provider network for testing and other development related purposes.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#recommended-prerequisites","title":"Recommended Prerequisites","text":"

    The following lists the recommended hardware requirements:

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#quickly-setup-local-greenfield-blockchain-network","title":"Quickly setup local Greenfield blockchain network","text":"
    1. Build Greenfield Blockchain

    Note Greenfield blockchain uses a lib which uses cgo, so you should set cgo env var; in addition, you should install gcc compiler in your OS.

    git clone https://github.com/bnb-chain/greenfield.git\ncd greenfield/\nexport CGO_ENABLED=1\nmake build\n

    If you encountered the following error messages while compiling greenfield blockchain, you should install glibc-static and libstdc++-static.

    # command-line-arguments\n/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1\n/bin/ld: cannot find -lstdc++\ncollect2: error: ld returned 1 exit status\n\nmake: *** [build] Error 1\n
    1. Start Greenfield Blockchain
    # 1 validator and 8 storage providers\nbash ./deployment/localup/localup.sh all 1 8\n
    1. Export the keys of SPs
    bash ./deployment/localup/localup.sh export_sps 1 8\n\n# result example\n# {\n#   \"sp0\": {\n#     \"OperatorAddress\": \"0x14539343413EB47899B0935287ab1111Df891d04\",\n#     \"FundingAddress\": \"0x21c6ff21DD7012DE1CCf9055f2eB234A44a1d3fB\",\n#     \"SealAddress\": \"0x8e424c6Db42Ad9A5d91b24e20b5f603eC70abbA3\",\n#     \"ApprovalAddress\": \"0x7Aa5C8B50696f1D15B3A60d6629f7318c605bb4C\",\n#     \"GcAddress\": \"0xfa238a4B262e1dc35c4970A2296A2444B956c9Ca\",\n#     \"MaintenanceAddress\": \"0xbE03316B1D7c3FCB69136e47e02442d6Fb3396dB\",\n#     \"OperatorPrivateKey\": \"ba6e97958d9c43d1ad54923eba99f8d59f54a0c66c78a5dcbc004c5c3ec72f8c\",\n#     \"FundingPrivateKey\": \"bd9d9e7823cd2dc7bc20f1b6676c3025cdda6cf5a8df9b04597fdff42c29af01\",\n#     \"SealPrivateKey\": \"aacd6b834627fdbc5de2bfdb1db31be0ea810a941854787653814c8040a9dd39\",\n#     \"ApprovalPrivateKey\": \"32108ed1a47c0af965824f84ac2162c029f347eec6d0988e642330b0ac264c85\",\n#     \"GcPrivateKey\": \"2fad16031b4fd9facb7dacda3da4ca4dd5f005f4166891bf9f7be13e02abb12d\",\n#     \"MaintenancePrivateKey\": \"cc38f4c004f73a810223776376a37a8ab3ed8204214f5a3a0a2f77f7bb5e2dc1\",\n#     \"BlsPrivateKey\": \"6f349866f18413abb1a78cab947933459042044649686f354e941a646b9ed6e7\"\n#   }\n#   ...\n# }\n

    These JSON data will be used for setup local SP network, so you\u2019d better save it as a json file:

    bash ./deployment/localup/localup.sh export_sps 1 8 > sp.json\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#setup-local-sp-network","title":"Setup local SP network","text":"
    1. Compile SP

    Users who want to compile SP can refer this doc.

    1. Generate localup env

    Use the following instruction to generate template config file, sp.info and db.info in seven different directories. This command is used for generating sp env the first time or regenerating sp env.

    # This command accepts four args, the first arg is json file path that only supports absolute path, the second arg is db user name,\n# the third arg is db password and the fourth arg is db address.\ncd greenfield-storage-provider/\nbash ./deployment/localup/localup.sh --generate json_file_path db_username db_password db_address\n

    The json file path accepted for the first arg is generated by quickly setup local greenfield blockchain network step3.

    View directory structure:

    ls deployment/localup/local_env/sp0\n\u251c\u2500\u2500 sp0\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 config.toml   # generated template config file\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 db.info       # generated db.info is used for config.toml\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 gnfd-sp0      # gnfd-sp binary\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 sp.info       # generated sp.info is used for config.toml\n\u251c\u2500\u2500 sp1\n\u251c\u2500\u2500 ...\n
    # An example for generating local sp env\ncd greenfield-storage-provider/\nbash ./deployment/localup/localup.sh --generate /root/sp.json root greenfield localhost:3306\n\n[root@yourmachine sp0]# cat db.info\n#!/usr/bin/env bash\nUSER=\"root\"                     # database username\nPWD=\"greenfield\"                # database password\nADDRESS=\"localhost:3306\"        # db endpoint, e.g. \"localhost:3306\"\nDATABASE=\"sp_0\"                 # database name\n\n[root@yourmachine sp0]# cat sp.info\n#!/usr/bin/env bash\nSP_ENDPOINT=\"127.0.0.1:9033\"                                                              # gateway endpoint, e.g. \"127.0.0.1:9033\"\nOPERATOR_ADDRESS=\"0x14539343413EB47899B0935287ab1111Df891d04\"                             # OperatorAddr is generated in setup local Greenfield blockchain step 3.\nOPERATOR_PRIVATE_KEY=\"ba6e97958d9c43d1ad54923eba99f8d59f54a0c66c78a5dcbc004c5c3ec72f8c\"   # OperatorPrivKey is generated in setup local Greenfield blockchain step 3.\nFUNDING_PRIVATE_KEY=\"bd9d9e7823cd2dc7bc20f1b6676c3025cdda6cf5a8df9b04597fdff42c29af01\"    # FundingPrivKey is generated in setup local Greenfield blockchain step 3.\nSEAL_PRIVATE_KEY=\"aacd6b834627fdbc5de2bfdb1db31be0ea810a941854787653814c8040a9dd39\"       # SealPrivKey is generated in setup local Greenfield blockchain step 3.\nAPPROVAL_PRIVATE_KEY=\"32108ed1a47c0af965824f84ac2162c029f347eec6d0988e642330b0ac264c85\"   # ApprovalPrivKey is generated in setup local Greenfield blockchain step 3.\nGC_PRIVATE_KEY=\"2fad16031b4fd9facb7dacda3da4ca4dd5f005f4166891bf9f7be13e02abb12d\"         # GcPrivateKey is generated in setup local Greenfield blockchain step 3.\nBLS_PRIVATE_KEY=\"6f349866f18413abb1a78cab947933459042044649686f354e941a646b9ed6e7\"        # BlsPrivateKey is generated in setup local Greenfield blockchain step 3.\n
    1. Start Eight SPs

    Make config.toml according to db.info, sp.info and start eight SPs.

    cd greenfield-storage-provider/\nbash ./deployment/localup/localup.sh --reset\nbash ./deployment/localup/localup.sh --start\n

    The environment directory is as follows:

    deployment/localup/local_env/\n\u251c\u2500\u2500 sp0\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 config.toml    # real config\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 data/          # piecestore data directory\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 db.info\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 gnfd-sp0\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 gnfd-sp.log    # gnfd-sp log file\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 log.txt\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 sp.info\n\u251c\u2500\u2500 sp1\n\u251c\u2500\u2500 ...\n

    Recompile SP

    If you want to modify config.toml in different sp directories or recompile gnfd-sp binary file, you can use the following commands to reset and start local sp:

    cd greenfield-storage-provider/\nbash ./deployment/localup/localup.sh --reset\nbash ./deployment/localup/localup.sh --start\n
    1. Supported commands
    # this command should be executed in greenfield-storage-provider/ directory.\nbash ./deployment/localup/localup.sh --help\n\nUsage: deployment/localup/localup.sh [option...] {help|generate|reset|start|stop|print}\n\n   --help            display help info\n   --generate        generate sp.info and db.info that accepts four args: the first arg is json file path, the second arg is db username, the third arg is db password and the fourth arg is db address\n   --reset           reset env\n   --start           start storage providers\n   --stop            stop storage providers\n   --clean           clean local sp env\n   --print           print sp local env work directory\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#operate-with-sp","title":"Operate With SP","text":"

    If you have already started Greenfield blockchain and Greenfield SP successfully in local, you can use Greenfield Cmd to operate with SP such as CreateBucket, PutObject and GetObject. Detailed info about Greenfield Cmd can be found here.

    Tip

    We strongly recommend you reading Greenfield Cmd. It will help you explore the functions of Greenfield blockchain and SP.

    Next, We provide you a hand by hand tutorial to operate with chain and SP.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#1-generate-your-test-account","title":"1. Generate your test account","text":"

    We firstly need to generate a test account and private key:

    cd greenfield/\n# this command will generate a test account whose name is testkey, you can change its name\n./build/bin/gnfd keys add testkey --keyring-backend os\n# export the private key of test account\n./build/bin/gnfd keys export testkey --unarmored-hex --unsafe --keyring-backend os\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#2-transefer-some-bnb-tokens-to-test-account","title":"2. Transefer some BNB tokens to test account","text":"

    After generating test account, there are no any tokens in this account. We should transefer some BNB tokens:

    cd greenfield/\n# transefer 5000 BNB tokens\n./gnfd tx bank send validator0 {generated_test_account_address} 500000000000000000000BNB --home /{your_greenfield_path}/greenfield/deployment/localup/.local/validator0 --keyring-backend test --node http://localhost:26750 -y\n# query your account balances\n./gnfd q bank balances {generated_test_account_address} --node http://localhost:26750\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#3-use-cmd-to-send-requests","title":"3. Use cmd to send requests","text":"

    If you come in this step, congratulations, you can operate with your own private chain and SP.

    First, we need to configure cmd:

    cd greenfield-cmd/\nmake build\ncd build/\n# generate a keystore file to manage private key information\ntouch key.txt & echo ${TEST_ACCOUNT_PRIVATE_KEY} > key.txt\ntouch password.txt & echo \"test_sp_function\" > password.txt\n./gnfd-cmd --home ./  --passwordfile password.txt account import key.txt \n\n# construct config.toml\ntouch config.toml\n{\n   echo rpcAddr = \\\"http://localhost:26750\\\"\n   echo chainId = \\\"greenfield_9000-121\\\"\n} > config.toml\n

    Second, you can do some operations with SP:

    1. Create bucket
    # list current available SPs\n./gnfd-cmd -c ./config.toml --home ./ sp ls\n# random choose one SP to create bucket\n./gnfd-cmd -c ./config.toml --home ./ bucket create gnfd://${BUCKET_NAME}\n# head bucket info\n./gnfd-cmd -c ./config.toml --home ./ bucket head gnfd://${BUCKET_NAME}\n# choose one sp to create bucket, operator_address is shown in sp ls result\n./gnfd-cmd -c ./config.toml --home ./ bucket create --primarySP ${operator_address} gnfd://${BUCKET_NAME}\n
    1. PutObject & GetObject
    # generate a 17MB random file\ndd if=/dev/urandom of=./random_file bs=17M count=1\n# put object\n./gnfd-cmd -c ./config.toml --home ./ object put --contentType \"application/octet-stream\" ./random_file gnfd://${BUCKET_NAME}/random_file\n# get object\n./gnfd-cmd -c ./config.toml --home ./ object get gnfd://${BUCKET_NAME}/random_file ./new_random_file\n

    Users can use md5 to compare your generated file and downloaded file whether is the same.

    You can explore other functions of Greenfield Cmd.

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/","title":"SP FAQ - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#what-are-requirements-for-greenfield-storage-provider","title":"What are requirements for Greenfield Storage Provider?","text":"

    Storage Providers(SP) should meet the following requirements: * Collateral: * Each SP candidate has to deposit 500 BNB as collateral * SP needs to pledge additional funds to store more data at 200% of the storage fees of the data stored as Primary SP, which is 0.023 * 1024 * 2 = $47.104/TB.

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#how-does-sp-receive-their-rewards","title":"How does SP receive their rewards?","text":"

    SP will receive their rewards in funding address after sending Settlement Transaction.

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#when-to-update-store-price-and-read-price","title":"When to update store price and read price?","text":"

    Every SP can set their own suggested store price and read price via on-chain transactions. Read how to send commands here

    There are some constrains: * When to Update : The global rates will be calculated and updated in each month\u2019s first block (UTC time) by default. * When not Update: By default, SPs cannot update their price in the last two days of the current month.

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#how-much-bnb-is-required-by-sp-to-stake-in-relation-to-how-much-space-they-want-to-provide","title":"How much BNB is required by SP to stake in relation to how much space they want to provide?","text":"

    SP needs to stake additional funds to store user\u2019s data. It\u2019s based on formula: storage_staking_price * stored_size, and the price is now 160000 wei/byte, which could be fetched from this API .

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#whats-the-limit-of-storage-provider-capacity","title":"What\u2019s the limit of Storage Provider capacity?","text":"

    Each VGF serves a limited number of buckets. Once the store size exceeds a specified threshold, the family will no longer allow to serve more buckets. No limit on number of VGF but max size per VGF is 64T

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#how-to-become-a-reliable-sp","title":"How to become a reliable SP?","text":"
    1. Make sure your SP passed this standard test
    2. If your infra is not working, switch your SP back to maintenance mode. Then, back up lost data from secondary SPs.
    "},{"location":"bnb-opbnb/","title":"opBNB - Layer2 Scaling Solution for BSC","text":"opBNB

    opBNB is the Layer 2 scaling solution for the BNB Smart Chain powered by bedrock version of Optimism OP Stack.

    Get Started

    Deposit BNB to opBNB to start your journey

    Summary of opBNB infrastructure

    Run Node

    Run a fullnode on opBNB network

    Build Dapp

    Deploy a simple HelloWorld smart contract on opBNB and build a Web3 frontend

    Multisig Wallet

    Use multi-sig wallet service based on the Gnosis Safe protocol to secure assets and projects

    "},{"location":"bnb-opbnb/overview/","title":"opBNB Overview - opBNB","text":""},{"location":"bnb-opbnb/overview/#opbnb-high-performance-layer-2-solution","title":"opBNB - High-performance layer 2 solution","text":"

    The opBNB network is the Layer 2 scaling solution for the BNB Smart Chain powered by bedrock version of Optimism OP Stack. It works by offloading transaction processing and resource usage from the BNB Smart Chain, while still posting data to the underlying mainnet. Users interact with the opBNB network by depositing funds from BSC and using applications and contracts on opBNB. Sequencers then aggregate transactions, compute state transitions and submit them to the rollup contract on BSC. Provers generate cryptographic proofs that prove the validity of these state transitions, and Verifiers check the proofs to verify the opBNB state is correct. At its core, opBNB allows users to deposit and withdraw funds, use smart contracts, and view network data with high throughput and low fees. By leveraging Layer 2, opBNB is able to scale beyond the constraints of the BNB Smart Chain and provide an improved experience for users.

    "},{"location":"bnb-opbnb/overview/#key-features-and-advantages","title":"Key Features and Advantages","text":"
    1. Optimistic Rollup Technology: opBNB employs Optimistic Rollup, a Layer-2 scaling solution that processes transactions off-chain while maintaining the security of the main BSC chain. By bundling multiple transactions into a single batch and then submitting them to the main chain, Optimistic Rollup reduces the computational load on BSC, resulting in faster and cheaper transactions.

    2. Increased Transaction Throughput: The adoption of Optimistic Rollup allows opBNB to achieve significantly higher transaction throughput compared to the BSC main chain. As of early 2024, opBNB supports up to 5,000 transactions per second (TPS), addressing one of the critical bottlenecks in blockchain scalability.

    3. Lower Transaction Fees: One of the primary benefits of opBNB is the reduction in transaction fees. By processing transactions off-chain and only settling the final state on the BSC main chain, opBNB dramatically lowers the costs associated with executing transactions. This makes it an attractive option for developers and users alike, particularly for micro-transactions and DeFi applications.

    4. Enhanced User Experience: With faster transaction confirmations and lower fees, opBNB significantly enhances the overall user experience. This improvement is crucial for the mass adoption of blockchain technology, as it makes interactions with DApps and DeFi platforms more seamless and affordable.

    5. Robust Security: Despite processing transactions off-chain, opBNB maintains a high level of security by relying on the security model of the underlying BSC main chain. Optimistic Rollup\u2019s fraud-proof mechanism ensures that any invalid transactions can be challenged and corrected, safeguarding the integrity of the network.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/","title":"Full Stack DApp - opBNB","text":""},{"location":"bnb-opbnb/advanced/full-stack-dapp/#create-a-full-stack-dapp-using-truffle-and-react-on-opbnb","title":"Create a Full Stack dapp using Truffle and React on opBNB","text":"

    In this tutorial, we\u2019ll deploy a simple HelloWorld smart contract on opBNB and build a Web3 frontend using React to interact with the deployed smart contract, i.e., read from and write to the opBNB blockchain.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#what-are-we-building","title":"What are we building","text":"

    opBNB is essentially an optimized layer-2 solution that delivers lower fees and higher throughput to unlock the full potential of the BNB Chain.

    For this tutorial, we will deploy a simple HelloWorld smart contract on the opBNB network and build a frontend using Reactjs to interact with the deployed smart contract for reading and writing data onto the opBNB blockchain. The HelloWorld smart contract is a simple string variable message that will be used for storing the user-defined messages, e.g., Hello, opBNB User. The updateMessage function will be used for updating the message variable to any user-defined string value.

    This smart contract will then be deployed on the opBNB network using Truffle IDE. We will then use the Reactjs boilerplate to build a front end to communicate with the smart contract. Web3.js library is used for interacting with the smart contract and reading and writing data to the opBNB blockchain. We further use Metamask for signing transactions and paying any gas costs.

    This is a basic example for educational purposes, and it assumes familiarity with Truffle, React, and MetaMask.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#learning-takeaways","title":"Learning Takeaways","text":"

    By the end of this tutorial, you will be able to achieve the following

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#pre-requisites","title":"Pre-requisites","text":""},{"location":"bnb-opbnb/advanced/full-stack-dapp/#demo-step-by-step-guide","title":"Demo Step-by-Step Guide","text":"

    For this tutorial, we will be using Truffle IDE to develop, compile and deploy a simple HelloWorld smart contract on the opBNB network. For building the front end, we will be using the create-react-app React boilerplate. Further, to connect our dapp to the web3 world, we will be using the Metamask wallet.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step-1-set-up-the-project","title":"Step 1: Set up the project","text":"
    1. Make sure you have Node.js and npm installed on your machine.

    2. Install Truffle globally by running the following command

      npm install -g truffle\n
    3. Create a new directory for your project and navigate into it

      mkdir HelloWorldDapp\ncd HelloWorldDapp\n
    4. Initialize a new Truffle project. Create a bare Truffle project which generates the required directory structure to test and deploy contracts:

      truffle init\n
      Truffle creates the following directory structure for your project:
    5. Install Create React App globally by running the following command

      npm install -g create-react-app\n
    6. Create the React app frontend using the following command

      npx create-react-app frontend\n
    7. Navigate into the client directory using the following command

      cd frontend\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step2-install-hdwallet-provider","title":"Step#2: Install hdwallet-provider\u200b","text":"

    hdwallet-provider is a separate package that signs transactions for addresses derived from a 12 or 24-word mnemonic. By default, the hdwallet-provider uses the first address generated from the mnemonic. However, this is configurable. For more information, refer to the Truffle hdwallet-provider repository. Run the following command to install hdwallet-provider

        npm install @truffle/hdwallet-provider\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step3-create-the-env-file","title":"Step#3: Create the .env file\u200b","text":"
        npm install dotenv\n
    MNEMONIC = \"<Your-MetaMask-Secret-Recovery-Phrase>\";\n

    Never disclose your secret recovery phrase. Anyone with your recovery phrase can steal any assets held in your wallet.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step4-create-the-smart-contract","title":"Step#4: Create the smart contract","text":"

    Inside the contracts directory, create a new file named HelloWorld.sol and add the following code

       // SPDX-License-Identifier: MIT\n   pragma solidity ^0.8.19;\n\n   contract HelloWorld {\n       string public message;\n\n       constructor(string memory _message) {\n           message = _message;\n       }\n\n       function updateMessage(string memory _newMessage) public {\n           message = _newMessage;\n       }\n   }\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step5-configure-truffle-for-use-with-opbnb","title":"Step#5: Configure Truffle for use with opBNB","text":"
    1. Open the truffle-config.js file and add the following code:

      const HDWalletProvider = require(\"@truffle/hdwallet-provider\");\n// create a file at the root of your project and name it .env -- there you can set process variables\n// like the mnemonic etc. Note: .env is ignored by git to keep your private information safe\n\nrequire(\"dotenv\").config();\n\nconst mnemonic = process.env[\"MNEMONIC\"].toString().trim();\n\nmodule.exports = {\n  networks: {\n    development: {\n      host: \"127.0.0.1\", // Localhost (default: none)\n      port: 8545, // Standard Ethereum port (default: none)\n      network_id: \"*\", // Any network (default: none)\n    },\n    opBNBTestnet: {\n      provider: () =>\n        new HDWalletProvider(\n          mnemonic,\n          `https://opbnb-testnet-rpc.bnbchain.org`\n        ),\n      network_id: 5611,\n      confirmations: 3,\n      timeoutBlocks: 200,\n      skipDryRun: true,\n    },\n  },\n\n  // Set default mocha options here, use special reporters etc.\n  mocha: {\n    // timeout: 100000\n  },\n\n  // Configure your compilers\n  compilers: {\n    solc: {\n      version: \"0.8.19\",\n    },\n  },\n};\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step6-deploy-the-smart-contract-on-opbnb","title":"Step#6: Deploy the smart contract on opBNB","text":"
    1. In the root directory of your project, create a new file named 1_deploy_contract.js inside the migrations directory and add the following code:

      const HelloWorld = artifacts.require(\"HelloWorld\");\n\nmodule.exports = function (deployer) {\n  deployer.deploy(HelloWorld, \"Hello, World!\");\n};\n
    2. Deploy the smart contract to the opBNB testnet by running the following command

      truffle migrate --network opBNBTestnet\n

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step7-set-up-the-react-frontend","title":"Step#7: Set up the React frontend","text":"
    1. Inside the frontend/src directory, replace the contents of the App.js file with the following code:

      import React, { useEffect, useState } from \"react\";\nimport Web3 from \"web3\";\nimport HelloWorldContract from \"./contracts/HelloWorld.json\";\nimport \"./App.css\";\n\nfunction App() {\n  const [contract, setContract] = useState(null);\n  const [message, setMessage] = useState(\"\");\n  const [newMessage, setNewMessage] = useState(\"\");\n  const [loading, setLoading] = useState(false);\n\n  useEffect(() => {\n    const loadBlockchainData = async () => {\n      try {\n        const web3 = new Web3(window.ethereum);\n        const networkId = await web3.eth.net.getId();\n        const deployedNetwork = HelloWorldContract.networks[networkId];\n        const instance = new web3.eth.Contract(\n          HelloWorldContract.abi,\n          deployedNetwork && deployedNetwork.address\n        );\n        setContract(instance);\n      } catch (error) {\n        console.error(error);\n      }\n    };\n\n    loadBlockchainData();\n  }, []);\n\n  const getMessage = async () => {\n    if (contract) {\n      try {\n        setLoading(true);\n        const message = await contract.methods.message().call();\n        setMessage(message);\n      } catch (error) {\n        console.error(error);\n      } finally {\n        setLoading(false);\n      }\n    }\n  };\n\n  const updateMessage = async () => {\n    if (contract && newMessage !== \"\") {\n      try {\n        setLoading(true);\n        await contract.methods\n          .updateMessage(newMessage)\n          .send({ from: (await window.ethereum.enable())[0] });\n        setNewMessage(\"\");\n      } catch (error) {\n        console.error(error);\n      } finally {\n        setLoading(false);\n      }\n    }\n  };\n\n  return (\n    <div className=\"App\">\n      <h1 className=\"header\">HelloWorld dApp</h1>\n      <div className=\"content\">\n        <div className=\"message\">\n          <h2>Current Message</h2>\n          <p className=\"messageValue\">{loading ? \"Loading...\" : message}</p>\n          <button onClick={getMessage}>Refresh</button>\n        </div>\n      </div>\n      <div className=\"content\">\n        <div className=\"update\">\n          <h2>Update Message</h2>\n          <input\n            type=\"text\"\n            placeholder=\"New Message\"\n            value={newMessage}\n            onChange={(e) => setNewMessage(e.target.value)}\n            className=\"inputMessage\"\n          />\n          <br />\n          <button onClick={updateMessage}>Update</button>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport default App;\n
    2. Replace the contents of the App.css file with the following code:

      .App {\n  text-align: center;\n}\n\n.header {\n  background-color: #f3ba2f;\n  min-height: 20vh;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  font-size: calc(40px + 2vmin);\n  color: white;\n}\n\n.content {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  padding: auto;\n  text-align: center;\n}\n\n.message,\n.update {\n  padding: auto;\n  margin: 20px;\n}\n.messageValue {\n  color: whitesmoke;\n  font-size: large;\n}\n\n.inputMessage {\n  float: center;\n  padding: 10px;\n  width: 100%;\n  font-family: \"IBM Plex Sans\", \"Raleway\", \"Source Sans Pro\", \"Arial\";\n}\n\nbutton {\n  float: center;\n  margin: 1em 0;\n  padding: 10px 3em;\n  font-weight: bold;\n  max-width: fit-content;\n  font-family: \"IBM Plex Sans\", \"Raleway\", \"Source Sans Pro\", \"Arial\";\n}\n\nbody {\n  background-color: #292929;\n  color: #f3ba2f;\n  align-items: center;\n  font-family: \"IBM Plex Sans\", \"Raleway\", \"Source Sans Pro\", \"Arial\";\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step8-start-the-development-server","title":"Step#8: Start the development server","text":"
    1. In the frontend directory, install the required dependencies by running the following command

      npm install\n
    2. Start the React development server:

      npm start\n
    3. Visit http://localhost:3000 in your browser, and you should see the HelloWorld dApp with the current message and the ability to update it.

      Make sure you have the MetaMask extension installed and set to the opBNB testnet.

    4. When you enter a new message and click the update button, if your dapp is already not connected to Metamask wallet, you will get a Metamask notification asking for permission to connect your wallet to the dapp.

    5. It will also ask for your confirmation to confirm the transaction. Proceed by clicking the confirm button.

    6. Once the transaction is confirmed, click the Refresh button to load the new message.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#conclusion","title":"Conclusion","text":"

    In this tutorial, we provided a step-by-step guide on how to develop, deploy, and interact with a smart contract on the opBNB network. We used the Truffle IDE for compiling and deploying the smart contract. We also build a React frontend to interact with the deployed smart contract, i.e., read from and write to the opBNB blockchain.

    "},{"location":"bnb-opbnb/advanced/local-dev-env/","title":"Local Development - opBNB","text":""},{"location":"bnb-opbnb/advanced/local-dev-env/#running-a-local-development-environment","title":"Running a local development environment","text":"

    Install and start the entire opbnb system locally, including L1 (BNB Smart Chain) and L2 development nodes. Running a local development environment is a great way to test the behavior of your code and contracts.

    "},{"location":"bnb-opbnb/advanced/local-dev-env/#how-to-do-it","title":"How to do it","text":"
    1. Make sure the following software is installed: golang, nodejs 16+, make, pnpm, python3, docker, foundry, poetry, jq Tips:

    Install Foundry by following the instructions located here. Please make sure your Foundry version matches the one described in opbnb/versions.json. If they do not match, please use a command such as foundryup -C xxxxxx to modify it.

    1. Clone opbnb monorepo:
        git clone git@github.com:bnb-chain/opbnb.git\n    cd opbnb\n
    1. Running pnpm install and then running pnpm build.
    2. Running make devnet-up and wait for the docker container to start.(The first run will be relatively slow because it needs to download the image and deploy the contract, and then it will be fast)
    3. Through the docker ps command, you can see that 5 containers have been started: ops-bedrock_l1_1, ops-bedrock_l2_1, ops-bedrock_op-node_1, ops-bedrock_op-batcher_1, ops-bedrock_op-proposer_1

    Now L1 is accessible at http://localhost:8545, and L2 is accessible at http://localhost:9545

    "},{"location":"bnb-opbnb/advanced/local-dev-env/#stop-or-clean","title":"Stop or clean","text":"

    To stop, run (in the root directory of the monorepo) make devnet-down. To clean everything, run (in the root directory of the monorepo) make devnet-clean. To view logs, run make devnet-logs

    "},{"location":"bnb-opbnb/advanced/local-dev-env/#notes","title":"Notes","text":"
    1. When executing for the first time, please be patient if you see the message \u201cWaiting for RPC server at\u2026\u201d, as the BSC network takes time to initialize.
    2. If you encounter an error during the \u201cDeploying contracts\u201d step, please try again as it usually recovers.
    "},{"location":"bnb-opbnb/advanced/local-dev-env/#additional-information","title":"Additional Information","text":"

    L1 chain ID is 714. L2 chain ID is 901.

    L1 test account:

    L2 test account:

    "},{"location":"bnb-opbnb/advanced/local-node/","title":"Run a Local Node - opBNB","text":""},{"location":"bnb-opbnb/advanced/local-node/#running-a-local-testnet-or-mainnet-node","title":"Running a Local Testnet or Mainnet Node","text":"

    If you\u2019re looking to build an app on opBNB you\u2019ll need access to an opBNB node. You can simply use the public rpc(Testnet: https://opbnb-testnet-rpc.bnbchain.org, Mainnet: https://opbnb-mainnet-rpc.bnbchain.org) or run your own node.

    This guide will walk you through setting up your own Testnet/Mainnet node.

    "},{"location":"bnb-opbnb/advanced/local-node/#hardware-requirements","title":"Hardware requirements","text":"

    Replicas must store the transaction history of opBNB and run Geth. For optimal performance, they should be powerful machines (real or virtual) with at least 16 GB RAM and an SSD drive with 500 GB free space (for production network).

    "},{"location":"bnb-opbnb/advanced/local-node/#fast-node","title":"Fast Node","text":"

    For users that just to run normal rpc node without debug functions, you can run the fast node which has faster sync speed and less hardware requirements.

    The fast node don\u2019t have MPT states and only use the snapshot to sync the latest state. The security is not as good as the full node, but it\u2019s enough for most of the users and validated in many production nodes. The advantage of the fast node is that it\u2019s faster to sync for it doesn\u2019t need to calculate the MPT states and store and query the MPT trees.

    You can start the fast node with the flags --allow-insecure-no-tries. The gc mode should not be archive if you start with the fast node.

    For more information, you can refer to the fast node pr.

    "},{"location":"bnb-opbnb/advanced/local-node/#run-with-docker","title":"Run with Docker","text":"

    There are official Docker images available for the opBNB node. You can use the latest versions of these images from the following links: - op-node - op-geth

    Additionally, you can find a docker-compose file example in this repository to run the opBNB node with Docker. This allows you to set up a Testnet/Mainnet node quickly, within minutes. If you use different infrastructure providers, please consult the docker-compose file and adjust the configuration as needed.

    "},{"location":"bnb-opbnb/advanced/local-node/#run-with-binaries","title":"Run with Binaries","text":""},{"location":"bnb-opbnb/advanced/local-node/#build-op-node-and-op-geth","title":"Build op-node and op-geth","text":"

    dependencies - golang 1.20+ - make - git - gcc - libc-dev

    You can refer to the Docker files for Alpine Linux: op-node and op-geth. If you are using a different OS, please find the alternative packages for your OS.

    export OPBNB_WORKSPACE=/tmp/opbnb\nmkdir -p $OPBNB_WORKSPACE\n\ncd $OPBNB_WORKSPACE\ngit clone https://github.com/bnb-chain/opbnb.git\ncd opbnb/op-node\ngit checkout develop\nmake op-node\nmkdir -p $OPBNB_WORKSPACE/op-node-data\ncp ./bin/op-node $OPBNB_WORKSPACE/op-node-data\n\ncd $OPBNB_WORKSPACE\ngit clone https://github.com/bnb-chain/op-geth.git\ncd op-geth\ngit checkout develop\nmake geth\nmkdir -p $OPBNB_WORKSPACE/op-geth-data\ncp ./build/bin/geth $OPBNB_WORKSPACE/op-geth-data/op-geth\n
    "},{"location":"bnb-opbnb/advanced/local-node/#data-preparation","title":"Data Preparation","text":"
    cd $OPBNB_WORKSPACE\n# for testnet\ncp $OPBNB_WORKSPACE/opbnb/assets/testnet/genesis.json $OPBNB_WORKSPACE/op-geth-data\n# for mainnet\n# cp $OPBNB_WORKSPACE/opbnb/assets/mainnet/genesis.json $OPBNB_WORKSPACE/op-geth-data\n\nopenssl rand -hex 32 > jwt.txt\ncp jwt.txt $OPBNB_WORKSPACE/op-geth-data\ncp jwt.txt $OPBNB_WORKSPACE/op-node-data\n\n# init op-geth genesis\ncd $OPBNB_WORKSPACE/op-geth-data\nmkdir datadir\n./op-geth --datadir ./datadir init genesis.json\n
    "},{"location":"bnb-opbnb/advanced/local-node/#start-components","title":"Start components","text":"

    op-geth

    #! /usr/bin/bash\ncd $OPBNB_WORKSPACE/op-geth-data\n\n# for testnet\nexport CHAIN_ID=5611\nexport L2_RPC=https://opbnb-testnet-rpc.bnbchain.org\nexport P2P_BOOTNODES=\"enr:-KO4QKFOBDW--pF4pFwv3Al_jiLOITj_Y5mr1Ajyy2yxHpFtNcBfkZEkvWUxAKXQjWALZEFxYHooU88JClyzA00e8YeGAYtBOOZig2V0aMfGhE0ZYGqAgmlkgnY0gmlwhDREiqaJc2VjcDI1NmsxoQM8pC_6wwTr5N2Q-yXQ1KGKsgz9i9EPLk8Ata65pUyYG4RzbmFwwIN0Y3CCdl-DdWRwgnZf,enr:-KO4QFJc0KR09ye818GT2kyN9y6BAGjhz77sYimxn85jJf2hOrNqg4X0b0EsS-_ssdkzVpavqh6oMX7W5Y81xMRuEayGAYtBSiK9g2V0aMfGhE0ZYGqAgmlkgnY0gmlwhANzx96Jc2VjcDI1NmsxoQPwA1XHfWGd4umIt7j3Fc7hKq_35izIWT_9yiN_tX8lR4RzbmFwwIN0Y3CCdl-DdWRwgnZf\"\n\n# for mainnet\n# export CHAIN_ID=204\n# export L2_RPC=https://opbnb-mainnet-rpc.bnbchain.org\n# export P2P_BOOTNODES=\"enr:-KO4QHs5qh_kPFcjMgqkuN9dbxXT4C5Cjad4SAheaUxveCbJQ3XdeMMDHeHilHyqisyYQAByfdhzyKAdUp2SvyzWeBqGAYvRDf80g2V0aMfGhHFtSjqAgmlkgnY0gmlwhDaykUmJc2VjcDI1NmsxoQJUevTL3hJwj21IT2GC6VaNqVQEsJFPtNtO-ld5QTNCfIRzbmFwwIN0Y3CCdl-DdWRwgnZf,enr:-KO4QKIByq-YMjs6IL2YCNZEmlo3dKWNOy4B6sdqE3gjOrXeKdNbwZZGK_JzT1epqCFs3mujjg2vO1lrZLzLy4Rl7PyGAYvRA8bEg2V0aMfGhHFtSjqAgmlkgnY0gmlwhDbjSM6Jc2VjcDI1NmsxoQNQhJ5pqCPnTbK92gEc2F98y-u1OgZVAI1Msx-UiHezY4RzbmFwwIN0Y3CCdl-DdWRwgnZf\"\n\n\n./op-geth \\\n  --datadir=\"./datadir\" \\\n  --verbosity=3 \\\n  --http \\\n  --http.corsdomain=\"*\" \\\n  --http.vhosts=\"*\" \\\n  --http.addr=0.0.0.0 \\\n  --http.port=8545 \\\n  --http.api=net,eth,engine \\\n  --ws \\\n  --ws.addr=0.0.0.0 \\\n  --ws.port=8545 \\\n  --ws.origins=\"*\" \\\n  --ws.api=eth,engine \\\n  --syncmode=full \\\n  --maxpeers=10 \\\n  --networkid=$CHAIN_ID \\\n  --miner.gaslimit=150000000 \\\n  --triesInMemory=32 \\\n  --txpool.globalslots=10000 \\\n  --txpool.globalqueue=5000 \\\n  --txpool.accountqueue=200 \\\n  --txpool.accountslots=200 \\\n  --cache 32000 \\\n  --cache.preimages \\\n  --allow-insecure-unlock \\\n  --authrpc.addr=\"0.0.0.0\" \\\n  --authrpc.port=\"8551\" \\\n  --authrpc.vhosts=\"*\" \\\n  --authrpc.jwtsecret=./jwt.txt \\\n  --gcmode=archive \\\n  --metrics \\\n  --metrics.port 6060 \\\n  --metrics.addr 0.0.0.0 \\\n  --rollup.sequencerhttp=$L2_RPC \\\n  --bootnodes=$P2P_BOOTNODES\n

    op-geth runs with PBSS(Path-Base Scheme Storage) and PebbleDB by adding the flags --state.scheme path and --db.engine pebble. It\u2019s recommended to start a new node with this mode, which provides better performance and less disk space usage.

    To start the op-geth node for a fast node, you can add the flag --allow-insecure-no-tries. but the gcmode should be full.

    op-node

    #! /usr/bin/bash\n\nset -ex\n\ncd op-node-data\n\nexport L2_RPC=http://localhost:8551\n# replace the p2p private key with yours\n# you can generate a new one with `openssl rand -hex 32`\nexport P2P_PRIV_KEY=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# for testnet\n# it's better to replace the L1_RPC with your own BSC Testnet RPC Endpoint for stability\nexport L1_RPC=https://bsc-testnet.bnbchain.org\nexport P2P_BOOTNODES=\"enr:-J24QGQBeMsXOaCCaLWtNFSfb2Gv50DjGOKToH2HUTAIn9yXImowlRoMDNuPNhSBZNQGCCE8eAl5O3dsONuuQp5Qix2GAYjB7KHSgmlkgnY0gmlwhDREiqaHb3BzdGFja4PrKwCJc2VjcDI1NmsxoQL4I9wpEVDcUb8bLWu6V8iPoN5w8E8q-GrS5WUCygYUQ4N0Y3CCIyuDdWRwgiMr,enr:-J24QJKXHEkIhy0tmIk2EscMZ2aRrivNsZf_YhgIU51g4ZKHWY0BxW6VedRJ1jxmneW9v7JjldPOPpLkaNSo6cXGFxqGAYpK96oCgmlkgnY0gmlwhANzx96Hb3BzdGFja4PrKwCJc2VjcDI1NmsxoQMOCzUFffz04eyDrmkbaSCrMEvLvn5O4RZaZ5k1GV4wa4N0Y3CCIyuDdWRwgiMr\"\n\n# for mainnet\n# export L1_RPC=https://bsc-dataseed.bnbchain.org\n# export P2P_BOOTNODES=\"enr:-J24QA9sgVxbZ0KoJ7-1gx_szfc7Oexzz7xL2iHS7VMHGj2QQaLc_IQZmFthywENgJWXbApj7tw7BiouKDOZD4noWEWGAYppffmvgmlkgnY0gmlwhDbjSM6Hb3BzdGFja4PMAQCJc2VjcDI1NmsxoQKetGQX7sXd4u8hZr6uayTZgHRDvGm36YaryqZkgnidS4N0Y3CCIyuDdWRwgiMs,enr:-J24QPSZMaGw3NhO6Ll25cawknKcOFLPjUnpy72HCkwqaHBKaaR9ylr-ejx20INZ69BLLj334aEqjNHKJeWhiAdVcn-GAYv28FmZgmlkgnY0gmlwhDTDWQOHb3BzdGFja4PMAQCJc2VjcDI1NmsxoQJ-_5GZKjs7jaB4TILdgC8EwnwyL3Qip89wmjnyjvDDwoN0Y3CCIyuDdWRwgiMs\"\n\n./op-node \\\n  --l1.trustrpc \\\n  --sequencer.l1-confs=15 \\\n  --verifier.l1-confs=15 \\\n  --l1.http-poll-interval 3s \\\n  --l1.epoch-poll-interval 45s \\\n  --l1.rpc-max-batch-size 20 \\\n  --rollup.config=./rollup.json \\\n  --rpc.addr=0.0.0.0 \\\n  --rpc.port=8546 \\\n  --p2p.sync.req-resp \\\n  --p2p.listen.ip=0.0.0.0 \\\n  --p2p.listen.tcp=9003 \\\n  --p2p.listen.udp=9003 \\\n  --snapshotlog.file=./snapshot.log \\\n  --p2p.bootnodes=$P2P_BOOTNODES \\\n  --metrics.enabled \\\n  --metrics.addr=0.0.0.0 \\\n  --metrics.port=7300 \\\n  --pprof.enabled \\\n  --rpc.enable-admin \\\n  --l1=${L1_RPC} \\\n  --l2=${L2_RPC} \\\n  --l2.jwt-secret=./jwt.txt \\\n  --l2.engine-sync=true \\\n  --l2.skip-sync-start-check=true \\  \n  --log.level=debug\n
    "},{"location":"bnb-opbnb/advanced/local-node/#run-with-snapshots","title":"Run with Snapshots","text":"

    To improve the synchronization speed of the node, you can utilize snapshots to initialize it.

    The most recent snapshot is maintained in the repository opbnb-snapshot. Please visit the repository for download links and usage instructions.

    "},{"location":"bnb-opbnb/advanced/local-node/#check-status","title":"Check status","text":"

    Wait for the node to sync. You\u2019ll see log in op-geth if there\u2019s any new block.

    INFO [11-15|10:10:05.569] Syncing beacon headers                   downloaded=1,762,304 left=11,403,991 eta=27m1.039s\nINFO [11-15|10:10:06.440] Forkchoice requested sync to new head    number=13,164,499 hash=d78cb3..a2e94d finalized=unknown\n

    You can check the block number with curl:

    $ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}' http://localhost:8545\n

    Once all headers have been downloaded, the node will begin downloading the blocks. You will notice that the block height is increasing.

    {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0x1a\"}\n

    To verify if the node has synchronized to the latest height, you can compare the block with the one requested from public endpoints.

    # local\n$ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"id\": 1, \"params\": [\"0x1a\", false]}' http://localhost:8545\n\n# testnet\n$ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"id\": 1, \"params\": [\"0x1a\", false]}' https://opbnb-testnet-rpc.bnbchain.org\n\n# mainnet\n$ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"id\": 1, \"params\": [\"0x1a\", false]}' https://opbnb-mainnet-rpc.bnbchain.org\n
    "},{"location":"bnb-opbnb/advanced/local-node/#troubleshooting","title":"Troubleshooting","text":"

    If the problem you are facing is not addressed here, please open an issue on GitHub by visiting this link: open an issue.

    "},{"location":"bnb-opbnb/advanced/local-node/#not-synced-for-a-long-time","title":"Not synced for a long time","text":"

    The default sync mechanism involves two P2P networks, the op-node network and op-geth network. If you are not connected to the op-node network, you can not receive the latest blocks from broadcast, and can\u2019t trigger the engine sync of op-geth. If you are not connected to the op-geth network, you can receive the latest blocks from broadcast, but can\u2019t get the historical blocks from op-geth P2P network.

    Check the op-geth logs.

    If you can find the following logs, it means that the op-node network is connected successfully and you are receiving the latest blocks from broadcast.

    INFO [11-15|10:32:02.801] Forkchoice requested sync to new head    number=8,290,596 hash=1dbff3..9a306a finalized=unknown\n

    If you can find the following logs, it means that the op-geth network is connected successfully and you are receiving the historical block headers from op-geth P2P network.

    INFO [11-15|10:32:52.240] Syncing beacon headers                   downloaded=210,432 left=8,084,773 eta=31m39.748s\n

    Check the op-node p2p network with the command below:

    $ curl -X POST -H \"Content-Type: application/json\" --data \\\n    '{\"method\":\"opp2p_peers\",\"params\":[true],\"id\":1,\"jsonrpc\":\"2.0\"}'  \\\n    http://localhost:8546\n

    Check the op-geth p2p network with the command below. You have to enable admin API in op-geth to use this API. Refer to https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-admin for more details.

    $ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"admin_peers\",\"params\":[],\"id\":1}' http://localhost:8545 | jq .\n
    "},{"location":"bnb-opbnb/advanced/local-node/#the-local-nodes-chain-has-forked-from-the-canonical-chain","title":"The local node\u2019s chain has forked from the canonical chain","text":"

    If your local node is already running and tracking blocks, the following situations may indicate that your local node\u2019s chain has forked from the canonical chain: 1. The block hash at the same height obtained through the eth_getBlockByNumber method does not match the data returned by the public node. 2. Your local chain consistently lags behind a fixed number of blocks and cannot catch up with the latest block height.

    In this case, we recommend that you check the code version of the running node through the following steps:

    $ op-node -v\nop-node version v0.0.0-515ebd51-1698742099\n\n$ op-geth version\nGeth\nVersion: 0.1.0-unstable\nGit Commit: f8871fc80dbf2aa0178b504e76c20c21b890c6d5\nGit Commit Date: 20231026\nUpstream Version: 1.11.5-stable\nArchitecture: arm64\nGo Version: go1.20.2\nOperating System: darwin\nGOPATH=\n
    Please make sure to use the latest code version. If the code version is incorrect, please completely clear the node data and run the new node again according to this guide.

    You also need to check if the genesis.json and rollup.json files are up to date.

    In the latest code, we hardcoded the configuration of rollup.json. Instead of using --rollup.config=./rollup.json, you just need to use --network=opBNBTestnet (for the mainnet network it is opBNBMainnet). This change ensures that the contents of rollup.json will not be incorrect.

    "},{"location":"bnb-opbnb/advanced/local-node/#node-block-is-stuck-and-op-geth-log-prints-database-compacting-degraded-performance-databasedatagethchaindata","title":"Node block is stuck and op-geth log prints: Database compacting, degraded performance database=/data/geth/chaindata","text":"

    If your node suddenly gets stuck and cannot grow, and your op-geth log keeps printing: Database compacting, degraded performance database=/data/geth/chaindata, then you need to consider upgrading your machine specifications, increasing CPU, memory, and disk maximum throughput.

    This is because the current OP Stack only supports the archive mode of Geth, and the disk space usage increases over time. The Leveldb that Geth relies on requires more machine resources to complete the compact process. We are working hard to support full mode Geth, and further support PBSS and Pebble to completely solve this problem.

    If you don\u2019t want to upgrade your machine\u2019s specifications, You can choose to download the pruned snapshot from the opbnb-snapshot repository, and use it to start a new node. The new node will not have this issue, but it will lose all state data before a certain block height.

    If you are an advanced player, you can also try to perform offline pruning on your nodes (Note that this is a dangerous operation and after pruning, the state data of the blocks before the target block height will no longer be available). You can follow these steps: 1. Shut down your machine and make sure that op-geth prints the following log: \u201cBlockchain stopped\u201d. 2. Search for the keyword \u201cChain head was updated\u201d in the logs to confirm the block height of the last inserted block before the node was shut down. For the sake of explanation, let\u2019s assume the block height is 16667495. 3. Wait for 16667495 to become the final state on the chain, ensuring that no reorganization has occurred. You can go to the blockchain explorer (https://opbnbscan.com/) to query this block height, and compare the block height hash with the one in the log. If the hashes match and a long time has passed, then we believe that this block height will not be reorganized. 4. Get the state root hash of this block height through JSON-RPC. 5. To execute pruning, use the following command: geth snapshot prune-state --datadir {yourDataDir} --triesInMemory=32 {targetBlockStateRootHash}, making sure to replace {yourDataDir} and {targetBlockStateRootHash} with your own values. 6. Be patient and observe the logs. The entire process may take dozens of hours. 7. Restart your node after pruning is complete.

    Info

    Pruning is very dangerous and may damage the data of the node. This could result in having to rerun the new node. Please only perform this operation if you are familiar with the process.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/","title":"Best Practices - opBNB Node Configuration","text":""},{"location":"bnb-opbnb/advanced/node-best-practices/#best-practices-for-opbnb-node-configuration","title":"Best Practices for opBNB Node Configuration","text":""},{"location":"bnb-opbnb/advanced/node-best-practices/#selecting-the-appropriate-mode-and-storage-scheme","title":"Selecting the Appropriate Mode and Storage Scheme","text":"

    opBNB accommodates various node modes: Full, Fast, and Archive. Two storage schemes are available: HBSS (Hash-Based Scheme Storage) and PBSS (Path-Based Scheme Storage).

    The principal distinctions between them lie in their methods of preserving history trie data.

    The Merkle Patricia Trie (MPT), an advanced data structure, is adept at storing and retrieving key-value pairs with efficiency. It amalgamates the principles of a Patricia trie and a Merkle tree to forge a secure and immutable representation of data within the Ethereum Virtual Machine (EVM).

    The MPT endows the following capabilities:

    Nevertheless, the preservation of entire history trie data on disk can demand substantial resources and may be superfluous for certain applications. opBNB introduces diverse node modes and storage schemes to accommodate a range of requirements.

    The variances between the modes and storage schemes are encapsulated as follows:

    Comparative Analysis of Node Modes and Storage Schemes:

    Mode Full Node (PBSS) Full Node (HBSS) Fast Node Archive Node Preserve Trie Nodes Latest 128 blocks Latest 128 blocks None All Disk Consumption Moderate-Low Moderate-High Lowest Highest Auto Prune History Trie Data Yes No Not Applicable Not Applicable Performance Moderate-High Moderate-Low Highest Lowest Security High High Lower than others since it doesn\u2019t verify the state root High"},{"location":"bnb-opbnb/advanced/node-best-practices/#fast-node","title":"Fast Node","text":"

    For most applications, operating a fast node is advisable. This mode maintains only the current state, sans trie data, making it suitable for tasks such as querying the current state and processing transactions.

    To activate the fast node, include --allow-insecure-no-tries in the op-geth startup command.

     ./geth --config ./config.toml --datadir ./node --syncmode full  --allow-insecure-no-tries\n

    To prune the MPT state (e.g., when transitioning from a full to a fast node), prune the node as follows:

    ./geth snapshot insecure-prune-all --datadir ./datadir ./genesis.json\n

    Fast Node does not generate Trie Data when syncing. Once the Fast Node is running, there is no way to switch back to Full Node. Need to re-download snapshot data to restore it to Full Node.

    For implementation details and further information, refer to the PR.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#full-node","title":"Full Node","text":"

    Operating a full node is recommended if you require:

    To enable the full node, set the --syncmode full flag in the geth command.

    It is particularly advised to operate a full node with PBSS and pebble to minimize data redundancy and enhance performance.

    --state.scheme path --db.engine pebble\n

    For comprehensive details, consult the PBSS document.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#archive-nodewith-op-reth","title":"Archive Node(with op-reth)","text":"

    The Archive node mode archives the entirety of history trie data. This mode is apt for scenarios necessitating access to the complete history trie data, such as block explorers and analytics.

    The current volume of history trie data approximates 3TB (as of the end of April, 2024). Significant performance issues may arise in the op-geth implementation when managing extensive history trie data. Therefore, it is recommended to operate the archive node in conjunction with op-reth.

    You can refer to Reth Node for opBNB for additional details.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#snapshots","title":"Snapshots","text":"

    The latest snapshot data is accessible via the opbnb-snapshot repository.

    Employing snapshot data can drastically curtail the time required for node synchronization.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#performance-optimization","title":"Performance Optimization","text":"

    In order to enhance the performance of op-geth, it is crucial to configure the cache settings appropriately. Allocating approximately one-third of the physical memory to the cache is advisable. For instance, if the system has 64GB of physical memory, the cache setting can be configured as:

    --cache 20000\n

    This allocation ensures that the cache is optimized for efficient use of system resources, ultimately leading to improved performance of op-geth.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#running-server-as-a-daemon","title":"Running Server as a Daemon","text":"

    To ensure continuous operation, it is important to keep op-node and op-geth running at all times. One of the simplest and recommended solutions is to register them as systemd service. By doing so, they will automatically start upon system reboots and other relevant events, ensuring seamless operation without manual intervention.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#security","title":"Security","text":""},{"location":"bnb-opbnb/advanced/node-best-practices/#securing-your-full-node-rpc-from-hackers","title":"Securing Your Full Node RPC from Hackers","text":"

    It is imperative to safeguard your Full Node RPC endpoints from unauthorized access. Exposing RPC endpoints to the public network can pose security risks, making it essential to restrict access and implement appropriate security measures to prevent unauthorized intrusion.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#software-vulnerabilities","title":"Software Vulnerabilities","text":"

    To ensure the security of your node and assets, it is crucial to download software only from official sources. Additionally, it is important to consistently update the software to the latest, most secure version available. By adhering to these practices, you can mitigate the risk of potential vulnerabilities and safeguard your node and assets from security threats.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#faq","title":"FAQ","text":""},{"location":"bnb-opbnb/advanced/node-best-practices/#why-does-my-node-experience-offline-status-or-block-height-lag-after-an-abrupt-termination","title":"Why does my node experience offline status or block height lag after an abrupt termination?","text":"

    After running a synchronized node for an extended period of time, abruptly terminating the node(op-geth process) can result in a period of offline status upon restart. Specifically, only archived nodes are expected to quickly re-synchronize after such an event.

    The reason for this behavior lies in the nature of Geth\u2019s functionality. When Geth experiences a crash or is not shut down gracefully, the recent state that was held in memory is lost and must be regenerated. As a result, it can take Geth a considerable amount of time to restore these states.

    The root cause of this prolonged restoration process can be attributed to the fact that Geth does flush the state trie periodically. The frequency of this flushing is defined by the trieTimeout parameter in the configuration file (config.toml). This periodic flushing is intended to maintain consistency and integrity within the node\u2019s state, but it also contributes to the time required for state regeneration in the event of an abrupt shutdown.

    "},{"location":"bnb-opbnb/advanced/reth-node/","title":"Reth Node - opBNB Develop","text":""},{"location":"bnb-opbnb/advanced/reth-node/#reth-node-for-opbnb","title":"Reth Node for opBNB","text":"

    OpBNB Reth is a Rust client developed to provide support for the opBNB network. It aims to enhance client diversity and performance on the BNB Chain.

    "},{"location":"bnb-opbnb/advanced/reth-node/#hardware-specifications","title":"Hardware Specifications","text":"

    To run OpBNB Reth effectively, ensure your system meets the following hardware requirements:

    "},{"location":"bnb-opbnb/advanced/reth-node/#running-opbnb-reth-node","title":"Running opBNB Reth Node","text":"

    The opBNB Reth is an execution client for opBNB network. You need to run op-node along with op-reth to synchronize with the opBNB network.

    It\u2019s important to note that both op-node and op-reth must use the same JWT secret file for authentication. You can use the following command to generate JWT secret file and copy to the workdir for running op-node and op-reth.

    openssl rand -hex 32 > jwt.txt\n
    "},{"location":"bnb-opbnb/advanced/reth-node/#running-op-node","title":"Running OP Node","text":"
    1. Download source code and build

      git clone https://github.com/bnb-chain/opbnb\ncd opbnb\nmake op-node\n
    2. Start op-node

      # for mainnet\nexport network=mainnet\nexport L1_RPC=https://bsc-dataseed.bnbchain.org\nexport P2P_BOOTNODES=\"enr:-J24QA9sgVxbZ0KoJ7-1gx_szfc7Oexzz7xL2iHS7VMHGj2QQaLc_IQZmFthywENgJWXbApj7tw7BiouKDOZD4noWEWGAYppffmvgmlkgnY0gmlwhDbjSM6Hb3BzdGFja4PMAQCJc2VjcDI1NmsxoQKetGQX7sXd4u8hZr6uayTZgHRDvGm36YaryqZkgnidS4N0Y3CCIyuDdWRwgiMs,enr:-J24QPSZMaGw3NhO6Ll25cawknKcOFLPjUnpy72HCkwqaHBKaaR9ylr-ejx20INZ69BLLj334aEqjNHKJeWhiAdVcn-GAYv28FmZgmlkgnY0gmlwhDTDWQOHb3BzdGFja4PMAQCJc2VjcDI1NmsxoQJ-_5GZKjs7jaB4TILdgC8EwnwyL3Qip89wmjnyjvDDwoN0Y3CCIyuDdWRwgiMs\"\n\n# for testnet\n# it's better to replace the L1_RPC with your own BSC Testnet RPC Endpoint for stability\n# export network=testnet\n# export L1_RPC=https://bsc-testnet.bnbchain.org\n# export P2P_BOOTNODES=\"enr:-J24QGQBeMsXOaCCaLWtNFSfb2Gv50DjGOKToH2HUTAIn9yXImowlRoMDNuPNhSBZNQGCCE8eAl5O3dsONuuQp5Qix2GAYjB7KHSgmlkgnY0gmlwhDREiqaHb3BzdGFja4PrKwCJc2VjcDI1NmsxoQL4I9wpEVDcUb8bLWu6V8iPoN5w8E8q-GrS5WUCygYUQ4N0Y3CCIyuDdWRwgiMr,enr:-J24QJKXHEkIhy0tmIk2EscMZ2aRrivNsZf_YhgIU51g4ZKHWY0BxW6VedRJ1jxmneW9v7JjldPOPpLkaNSo6cXGFxqGAYpK96oCgmlkgnY0gmlwhANzx96Hb3BzdGFja4PrKwCJc2VjcDI1NmsxoQMOCzUFffz04eyDrmkbaSCrMEvLvn5O4RZaZ5k1GV4wa4N0Y3CCIyuDdWRwgiMr\"\n\n./op-node/bin/op-node \\\n  --l1.trustrpc \\\n  --sequencer.l1-confs=15 \\\n  --verifier.l1-confs=15 \\\n  --l1.http-poll-interval 60s \\\n  --l1.epoch-poll-interval 180s \\\n  --l1.rpc-max-batch-size 20 \\\n  --rollup.config=./assets/${network}/rollup.json \\\n  --rpc.addr=0.0.0.0 \\\n  --rpc.port=8546 \\\n  --p2p.sync.req-resp \\\n  --p2p.listen.ip=0.0.0.0 \\\n  --p2p.listen.tcp=9003 \\\n  --p2p.listen.udp=9003 \\\n  --snapshotlog.file=./snapshot.log \\\n  --p2p.bootnodes=$P2P_BOOTNODES \\\n  --metrics.enabled \\\n  --metrics.addr=0.0.0.0 \\\n  --metrics.port=7300 \\\n  --pprof.enabled \\\n  --rpc.enable-admin \\\n  --l1=${L1_RPC} \\\n  --l2=http://localhost:8551 \\\n  --l2.jwt-secret=./jwt.txt \\\n  --syncmode=execution-layer\n
    "},{"location":"bnb-opbnb/advanced/reth-node/#running-opbnb-reth-archive-node","title":"Running opBNB Reth Archive Node","text":"
    1. Download source code and build

      git clone https://github.com/bnb-chain/reth.git\ncd reth\nmake build-op\n
    2. Start op-reth

      # for mainnet\nexport network=mainnet\nexport L2_RPC=https://opbnb-mainnet-rpc.bnbchain.org\n\n# for testnet\n# export network=testnet\n# export L2_RPC=https://opbnb-testnet-rpc.bnbchain.org\n\n./target/release/op-reth node \\\n    --datadir=./datadir \\\n    --chain=opbnb-${network} \\\n    --rollup.sequencer-http=${L2_RPC} \\\n    --authrpc.addr=\"0.0.0.0\" \\\n    --authrpc.port=8551 \\\n    --authrpc.jwtsecret=./jwt.txt \\\n    --http \\\n    --http.api=\"eth, net, txpool, web3, rpc\" \\\n    --log.file.directory ./datadir/logs\n
    3. Alternatively, you can run the op-reth node with docker

      # for mainnet\nexport network=mainnet\nexport L2_RPC=https://opbnb-mainnet-rpc.bnbchain.org\n\n# for testnet\n# export network=testnet\n# export L2_RPC=https://opbnb-testnet-rpc.bnbchain.org\n\n# check this for version of the docker image, https://github.com/bnb-chain/reth/pkgs/container/op-reth\nexport version=latest\n\n# the directory where reth data will be stored\nexport data_dir=/xxx/xxx\n\n# the directory where the jwt.txt file is stored\nexport jwt_dir=/xxx/xxx\n\ndocker run -d -p 8545:8545 -p 30303:30303 -p 30303:30303/udp -v ${data_dir}:/data -v ${jwt_dir}:/jwt \\\n    --name op-reth ghcr.io/bnb-chain/op-reth:${version} node \\\n    --datadir=/data \\\n    --chain=opbnb-${network} \\\n    --rollup.sequencer-http=${L2_RPC} \\\n    --authrpc.addr=\"0.0.0.0\" \\\n    --authrpc.port=8551 \\\n    --authrpc.jwtsecret=/jwt/jwt.txt \\\n    --http \\\n    --http.api=\"eth, net, txpool, web3, rpc\" \\\n    --log.file.directory /data/logs\n
    "},{"location":"bnb-opbnb/advanced/reth-node/#running-opbnb-reth-full-node","title":"Running opBNB Reth Full Node","text":"

    To run a full node, simply add the --full flag when starting the op-reth node.

    "},{"location":"bnb-opbnb/advanced/reth-node/#benchmark-results","title":"Benchmark Results","text":"

    We benchmark Reth(v1.0.0), op-nodes(v0.4.2) on AWS i4g.4xlarge(16 core 128G) instance with NVMe SSD for opBNB. It may take approximately 53 hours to sync the latest block on opBNB mainnet for an archive node and 50 hours for a full node.

    The op-reth supports Stage Sync which is rearchitected for better performance for the initial sync from genesis and Live Sync. The following table displays the total time to stage sync and storage distribution after catch up on opBNB network:

    The result shows an encouraging 690 MGas/s result on historical sync in the last 1M blocks (the historical sync numbers represent pure execution time during \u201cbackfills\u201d).

    The live sync performance on the opBNB network is not very optimistic. We conducted an observation of the metrics for blocks [30467068, 30429919].

    The main reason for the underperformance of Live sync is that mdbx is not a write-friendly database. The commit db at the end of block execution takes up several tens of milliseconds, a challenge that becomes more pronounced for fast-blocking layer 2 solutions like opBNB.

    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/","title":"Run op-geth with PBSS and PebbleDB - opBNB","text":""},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#how-to-run-op-geth-with-pbss-and-pebbledb","title":"How to Run op-geth with PBSS and PebbleDB","text":"

    To start op-geth with PBSS and PebbleDB, include the following flags:

    --state.scheme path --db.engine pebble\n

    Info

    We recommend using version v0.3.1-alpha or later to activate this feature.

    Upon successful startup, the logs will confirm the initiation of PBSS and PebbleDB:

    INFO [03-21|07:00:25.684] Using pebble as the backing database\nINFO [03-21|07:00:47.039] State scheme set by user                 scheme=path\n
    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#pbss-path-based-scheme-storage","title":"PBSS (Path-Based Scheme Storage)","text":"

    PBSS stores trie nodes on disk using the encoded path and a specific key prefix as the key. This approach allows PBSS\u2019s Merkle Patricia Trie (MPT) to overwrite older data due to the shared key between the account trie and storage trie. This feature not only enables online pruning but also significantly reduces data redundancy.

    PBSS architecture comprises 128 difflayers (in memory) and one disk layer, as depicted below. Difflayers store only the state data changes.

    +-------------------------------------------+\n| Block X+128 State                         |\n+-------------------------------------------+\n| Block X+127 State                         |\n+-------------------------------------------+\n|              .......                      |\n+-------------------------------------------+\n| Block X+1 State, Bottom-most diff layer   |\n+-------------------------------------------+\n| Block X State, Disk layer (singleton trie)|\n+-------------------------------------------+\n

    PBSS offers superior read performance, with faster trie access and iteration. It maintains a single version of the state trie on disk and keeps new tries (changes to the state/storage/account trie) only in memory.

    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#restrictions","title":"Restrictions","text":"

    RPC requests requiring data beyond this range will return an error: missing trie node ${hash} (path ${path}). Only RPC methods that need to query trie data, such as eth_getProof, will be impacted by this limitation, while others will remain unaffected.

    This function might require querying state data from an hour earlier to obtain a withdrawal proof, which is not supported yet. Future versions will address this limitation.

    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#pebbledb","title":"PebbleDB","text":"

    PebbleDB, now the default database for the community, has been integrated into go-ethereum. It replaces LevelDB, which lacks a throttle mechanism for flushes and compactions, leading to latency spikes during intense read and write operations.

    Conversely, PebbleDB features separate rate limiters for flushes and compactions, conducting operations as needed and reducing unnecessary disk bandwidth consumption.

    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#faq","title":"FAQ","text":""},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#can-i-change-the-statescheme-or-dbengine-for-an-existing-node","title":"Can I change the state.scheme or db.engine for an existing node?","text":"

    No, you cannot change the state.scheme or db.engine for an existing node. You must start a new node with the desired configuration.

    "},{"location":"bnb-opbnb/advanced/verify-on-opbnbscan/","title":"Verify on opbnbscan - opBNB","text":""},{"location":"bnb-opbnb/advanced/verify-on-opbnbscan/#use-opbnbscan-to-verify-your-contract-via-hardhat-and-truffle","title":"Use opBNBScan to verify your contract via Hardhat and Truffle","text":"

    opBNBScan provides a convenient and user-friendly platform for developers to verify their smart contracts using popular developer tools like Truffle and Hardhat. Here are the step-by-step instructions to get started with opBNBScan\u2019s smart contract verification APIs.

    1. Go to the NodeReal portal and click the Login button.
    2. Login with your github account or discord account.
    3. And create your API key by clicking the create new key button.
    4. Copy your API key to your clipboard and and use it as your key of smart verification contract APIs.
    "},{"location":"bnb-opbnb/advanced/verify-on-opbnbscan/#hardhat","title":"Hardhat","text":"

    You can use the hardhat-verify plugin to verify your deployed smart contract. You can follow the steps in the hardhat document. Below is an example of how to configure your hardhat.config.js. Pay attention to the network\u2019s configuration settings, and replace the corresponding settings that meet your requirements.

    require(\"@nomicfoundation/hardhat-toolbox\");\nrequire(\"@nomicfoundation/hardhat-verify\");\n/** @type import('hardhat/config').HardhatUserConfig */\n\nmodule.exports = {\n  solidity: \"0.8.19\", //replace your own solidity compiler version\n  networks: {\n    opbnb: {\n      url: \"https://opbnb-testnet-rpc.bnbchain.org/\",\n      chainId: 5611, // Replace with the correct chainId for the \"opbnb\" network\n      accounts: [\"{{YOUR-PRIVATE-KEY}}\"], // Add private keys or mnemonics of accounts to use\n      gasPrice: 20000000000,\n    },\n  },\n  etherscan: {\n    apiKey: {\n      opbnb: \"{{YOUR-NODEREAL-API-KEY}}\", //replace your nodereal API key\n    },\n\n    customChains: [\n      {\n        network: \"opbnb\",\n        chainId: 5611, // Replace with the correct chainId for the \"opbnb\" network\n        urls: {\n          apiURL:\n            \"https://open-platform.nodereal.io/{{YOUR-NODEREAL-API-KEY}}/op-bnb-testnet/contract/\",\n          browserURL: \"https://testnet.opbnbscan.com/\",\n        },\n      },\n    ],\n  },\n};\n
    "},{"location":"bnb-opbnb/advanced/verify-on-opbnbscan/#truffle","title":"Truffle","text":"

    You can also use truffle to verify your smart contract on opBNBScan.

    Please make sure the truffle-plugin-verify is installed correctly, and in the plugin, add the \u2018truffle-plugin-verify\u2019

    module.exports = {\n plugins: [\n  'truffle-plugin-verify'\n ],\n networks:\n {\n  development: {\n    host: \"127.0.0.1\", // Localhost (default: none)\n    port: 8545, // Standard port (default: none)\n    network_id: \"*\", // Any network (default: none)\n    },\n    dashboard: {\n    verify: {\n    apiUrl: 'https://open-platform.nodereal.io/{{YOUR-NODEREAL-API-KEY}}/op-bnb-testnet/contract/',\n    apiKey: '{{YOUR-NODEREAL-API-KEY}}',\n    explorerUrl: 'https://testnet.opbnbscan.com/',\n        },\n            host: \"127.0.0.1\",\n            port: 24012,\n            network_id: \"*\"\n        },\n },\n// Set default mocha options here, use special reporters, etc.\nmocha: {\n// timeout: 100000\n},\n// Configure your compilers\ncompilers: {\n    solc: {\n        version: \"0.8.15\", // Fetch exact version from solc-bin (default: truffle's version)\n    }\n},\n

    Make sure your smart contract is deployed first. I am using the dashboard to avoid saving your private credentials to your local machine.

    npx truffle migrate \u2013network dashboard\n

    And then you can verify your smart contract by specifying your contract name

    npx truffle run verify {{Your-Contract-Name}} --network dashboard\n

    Then you can go to the opBNBScan explorer to check if your smart contract has been verified.

    Info

    For the mainnet contract verification, please change the following URLs: url: \u201chttps://opbnb-testnet-rpc.bnbchain.org/\u201d change to \u201chttps://opbnb-mainnet-rpc.bnbchain.org/\u201d apiUrl: \u2018https://open-platform.nodereal.io/{{YOUR-NODEREAL-API-KEY}}/op-bnb-testnet/contract/\u2019 change to \u2018https://open-platform.nodereal.io/{{YOUR-NODEREAL-API-KEY}}/op-bnb-mainnet/contract/\u2018

    "},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/","title":"Account Abstraction - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/#account-abstraction","title":"Account Abstraction","text":""},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/#opbnb-is-a-cost-efficient-solution-for-aa","title":"opBNB is a cost-efficient solution for AA","text":"

    The primary allure of opBNB lies in its ability to significantly reduce the gas costs associated with AA (ERC4337) transactions. This efficiency is achieved through optimized transaction processing and a more streamlined approach to handling complex operations typically found in AA transactions. AA transactions, with their intricate operations and smart contract interactions, traditionally require more computational resources. opBNB, however, utilizes innovative methods to simplify these processes, ensuring that the complexity does not translate into prohibitive costs for users and developers.

    "},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/#enhanced-transaction-speed-with-lower-costs","title":"Enhanced transaction speed with lower costs","text":"

    Not only does opBNB address the cost issue, but it also offers higher Transaction Per Second (TPS) rates. This combination of low cost and high speed is particularly crucial for dApps that require both efficiency and scalability, making opBNB a ideal choice for High-Frequency DeFi and web3 games. By integrating opBNB, dApp developers can offer their users a seamless experience without the burden of high transaction fees. This user-friendly approach, coupled with cost-effective operations, positions opBNB as a preferred choice in the AA landscape.

    "},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/#opbnb-aa-infrastructure","title":"opBNB AA Infrastructure","text":"

    Notably, platforms like Biconomy and Particle Wallet have already adopted opBNB\u2019s AA solutions. Their integration showcases the practical application and effectiveness of opBNB in managing the complexity and cost of AA transactions in real-world scenarios. For details, please refer to the blog of Account Abstraction current and future development on BNB Chain.

    "},{"location":"bnb-opbnb/core-concepts/gas-and-fees/","title":"Why OP Stack - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/gas-and-fees/#gas-and-fees","title":"Gas and Fees","text":"

    OpBNB is a Layer 2 scaling solution that aims to achieve higher throughput and lower cost for transactions on the BNB Smart Chain. The cost of opBNB transactions consists of two components: the Layer 2 gas fee and the Layer 1 gas fee. The Layer 2 gas fee reflects the computational complexity of the transaction. The Layer 1 gas fee covers the expense of submitting batches of transactions to the BSC for verification and finality.

    Gas price = base price + priority price

    Layer 2 transaction cost = Layer 2 gas price x Layer 2 gas consumed + Layer 1 gas price x Layer 1 gas consumed.

    "},{"location":"bnb-opbnb/core-concepts/gas-and-fees/#current-configuration","title":"Current configuration","text":"Name Floor Base Price Minimum Priority Price opBNB Testnet 8 wei (dynamic) 1001 wei opBNB Mainnet 8 wei (dynamic) 1001 wei BSC Testnet 0 3 BSC Mainnet 0 3"},{"location":"bnb-opbnb/core-concepts/gas-and-fees/#what-does-this-means","title":"What does this means","text":"

    Please note the floor base price is the minimum base price opBNB can set, and according to the usage, the base price can fluctuate. For example, according to the current configuration, if the usage of a block reaches 50% of 100M gas, the base price will increase by 12.5%.

    The minimum priority price is preconfigured, and users can give any priority price that is higher than this number. Usually users will get the estimate gas price by calling the API of \u201cestimate gas price\u201d. It is a recommended gas price according to the current average gas price of history blocks.

    BNB Chain aims to reduce the transaction cost to the level that enable the mass adoption, for opBNB, the target of the transfer transaction is lower than $0.001.

    "},{"location":"bnb-opbnb/core-concepts/gas-and-fees/#how-opbnb-keep-reducing-the-cost-of-l2-transactions","title":"How opBNB keep reducing the cost of L2 transactions","text":"
    1. Enhanced Data Compression: Implementing more advanced data compression algorithms to reduce the size of L2 transaction data before submitting it to L1.

    2. Efficient Transaction Batching: Optimizing how transactions are batched together to maximize space efficiency and reduce costs per transaction.

    3. Data Availability Solutions: Utilizing solutions like those in BNB Greenfield for offloading some data storage from the main chain, thereby reducing data costs.

    4. Zero-Knowledge Proofs: Employing zero-knowledge proofs to validate transactions without disclosing full transaction data, thus minimizing L1 data load.

    5. Protocol-Level Optimizations: Making improvements at the protocol level to reduce overhead in transaction processing on L2.

    "},{"location":"bnb-opbnb/core-concepts/opbnb-metrics/","title":"opBNB Metrics - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/opbnb-metrics/#opbnb-metrics","title":"opBNB Metrics","text":"

    Compared with other L2 solutions on the Ethereum, like OP Mainnet and Arbitrum, opBNB has lower gas fee, and higher block gas limit, which means the gas fee will be more stable when traffic of Layer 2 increases. I listed the Ethereum EIP-1559 parameters as a reference. Arbitrum gas mechanism is based on the ArbOS, it is not applicable here.

    Gas Parameter Differences

    Parameter opBNB value Optimism value Block gas limit 100,000,000 gas 30,000,000 gas Block gas target 50,000,000 gas 5,000,000 gas EIP-1559 elasticity multiplier 2 6 EIP-1559 denominator 8 50 Maximum base fee increase (per block) 12.5% 10% Maximum base fee decrease (per block) 12.5% 2%

    Metrics Differences

    opBNB Optimism Arbitrum Gas Token BNB ETH ETH VM EVM EVM EVM Gas Fee $0.001 $0.05 $0.1 Block Gas Limit 100M(150M 2024Q1) 30M 32M Block time 1s 2s 0.25s(Min) Withdraw/ Finality 7 days 7 days 7 days TPS (Transfer) 4500+ 700+ 4000+

    OP Stack has some minor differences, so does opBNB. I just listed the differences here for your reference, for details you can refer to the OP Stack documents.

    Our goal is to provide a scaling solution for network congestion problems for highly active applications on the BSC, such as DeFi, NFTs and gaming. opBNB is based on OP Stack and with optimizations of the mining process and the cache data access to achieve a capacity of 100M gas per second, which is much higher than BSC.

    opBNB BSC Ethereum Gas Token BNB BNB ETH VM EVM EVM EVM Gas Price Model EIP-1559 Gas Price Auction EIP-1559 Block Gas Limit 100M 140M 30M Block time 1s 3s 12s Transaction Cost $0.001 $0.03 $1

    Unlike opBNB and OP Mainnet, which have fixed blocktimes, Arbitrum has a variable blocktime that depends on the number and gas of transactions in a block. The more transactions and gas a block contains, the longer it takes to mine. The minimum blocktime on Arbitrum is 0.25 seconds, which means that the fastest block can be mined in a quarter of a second.

    "},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/","title":"Protocol Addresses","text":""},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#opbnb-protocol-addresses","title":"opBNB Protocol addresses","text":"

    The opBNB protocol contracts are smart contracts that enable the execution of transactions on the opBNB network. The main contracts are:

    Testnet:

    Name Address Batch Sender 0x1Fd6A75CC72f39147756A663f3eF1fc95eF89495 Batch Inbox 0xfF00000000000000000000000000000000005611 Output Proposer 0x4aE49f1f57358c13A5732cb12e656Cf8C8D986DF

    Mainnet:

    Name Address Batch Sender 0xef8783382eF80Ec23B66c43575A6103dECA909c3 Batch Inbox 0xff00000000000000000000000000000000000204 Output Proposer 0xc235c904AD9EfcABfF4628E3279994A4c0A9d591"},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#_1","title":"Protocol Addresses","text":""},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#l1-contract-addresses","title":"L1 Contract Addresses","text":"

    Testnet

    Name Description Address L1CrossDomainMessenger responsible for facilitating cross-domain communication on Layer 1 (L1) 0x5b0c605c707979e8bDc2Ad9271A0388b3fD4Af3E L1ERC721Bridge This contract is likely an ERC-721 bridge that enables the transfer of non-fungible tokens (NFTs) between L1 and L2 0xad39e2cfa7d8d8B6c2d56244Bfb88990EC31Bb79 L1ERC721BridgeProxy A proxy contract that may provide additional functionalities for the L1ERC721Bridge contract. 0x17e1454015bFb3377c75bE7b6d47B236fd2ddbE7 L1StandardBridge A standard bridge contract that enables the transfer of fungible tokens between L1 and L2. 0xddB9EB847971DaA82e5dbe2745C429A3B2715B46 L2OutputOracle This contract is an oracle on Layer 2 that provides output data to be used in smart contracts and applications 0xD92aEF4473093C67A7696e475858152D3b2acB7c L2OutputOracleProxy A proxy contract related to the L2OutputOracle, providing an interface or additional functionality. 0xFf2394Bb843012562f4349C6632a0EcB92fC8810 Lib_AddressManager This contract is a library used to manage addresses for various contracts in the system. 0x4d07b9B1ffC70Fc824587573cfb6ef1Cc404AaD7 OptimismMintableERC20Factory This is a factory contract for creating mintable ERC-20 tokens on the Layer 2 network. 0x1AD11eA5426bA3A11c0bA8c4B89fd1BCa732025E OptimismMintableERC20FactoryProxy A proxy contract related to the OptimismMintableERC20Factory, providing an interface or additional functionality. 0x182cE4305791744202BB4F802C155B94cb66163B OptimismPortal This contract serves as a portal or gateway for interacting with the Optimism Layer 2 network. 0x2d5D7bEe8ebEf17DE14dd6ADAE8271507994a6E0 OptimismPortalProxy A proxy contract related to the OptimismPortal, providing an interface or additional functionality. 0x4386C8ABf2009aC0c263462Da568DD9d46e52a31 PortalSender This contract is involved in sending data or messages to a portal or gateway on the L1. 0x02B668393Bc41415Dbb973C9dC144fDD42B8fA2D ProxyAdmin This contract is responsible for managing proxy contracts, allowing for upgrades and access control. 0xE4925bD8Ac30b2d4e2bD7b8Ba495a5c92d4c5156 Proxy__OVM_L1CrossDomainMessenger This contract is a proxy for the L1CrossDomainMessenger contract on the Layer 2, enabling interaction with the Layer 2 contract from Layer 1. 0xD506952e78eeCd5d4424B1990a0c99B1568E7c2C Proxy__OVM_L1StandardBridge This is a proxy for the L1StandardBridge contract on the Layer 2 network, allowing interaction with the Layer 2 bridge from Layer 1. 0x677311Fd2cCc511Bbc0f581E8d9a07B033D5E840 SystemConfig This contract is responsible for managing system configurations, settings, or parameters in the protocol. 0x8Fc086Ec0ac912D5101Fec3E9ac6D910eBD5b611 SystemConfigProxy A proxy contract related to the SystemConfig contract, providing an interface or additional functionality. 0x406aC857817708eAf4ca3A82317eF4ae3D1EA23B SystemDictator This contract has a role in managing or governing certain aspects of the system or protocol. 0x281cc8F04AE5bb873bADc3D89059423E4c664834 SystemDictatorProxy A proxy contract related to the SystemDictator contract, providing an interface or additional functionality. 0xB9Edfded1254ca07085920Af22BeCE0ce905F2AB"},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#_2","title":"Protocol Addresses","text":"

    Mainnet

    Name Description Address L1CrossDomainMessenger responsible for facilitating cross-domain communication on Layer 1 (L1) 0x09525eB7eEd671582dDc6f02f8D9082cbd55A606 L1ERC721Bridge This contract is likely an ERC-721 bridge that enables the transfer of non-fungible tokens (NFTs) between L1 and L2 0xCB4CD5B74A2f2D75076Fb097Da70cEF5FEaC0428 L1ERC721BridgeProxy A proxy contract that may provide additional functionalities for the L1ERC721Bridge contract. 0xC7c796D3B712ad223Bc29Bf85E6cdD3045D998C4 L1StandardBridge A standard bridge contract that enables the transfer of fungible tokens between L1 and L2. 0x6df37de57D50eC5a0600510eB8F563F538BDc403 L2OutputOracle This contract is an oracle on Layer 2 that provides output data to be used in smart contracts and applications 0x0d61A015BAeF63f6740afF8294dAc278A494f6fA L2OutputOracleProxy A proxy contract related to the L2OutputOracle, providing an interface or additional functionality. 0x153CAB79f4767E2ff862C94aa49573294B13D169 Lib_AddressManager This contract is a library used to manage addresses for various contracts in the system. 0x29cfb9A803589Ff5C37f955ead83b45311F15b12 OptimismMintableERC20Factory This is a factory contract for creating mintable ERC-20 tokens on the Layer 2 network. 0x6560F2822c9dFb9801F5E9A7c7CE1564c8c2b461 OptimismMintableERC20FactoryProxy A proxy contract related to the OptimismMintableERC20Factory, providing an interface or additional functionality. 0xAa53ddCDC64A53F65A5f570cc13eB13529d780f1 OptimismPortal This contract serves as a portal or gateway for interacting with the Optimism Layer 2 network. 0x7e2419F79c9546B9A0E292Fd36aC5005ffed5495 OptimismPortalProxy A proxy contract related to the OptimismPortal, providing an interface or additional functionality. 0x1876EA7702C0ad0C6A2ae6036DE7733edfBca519 PortalSender This contract is involved in sending data or messages to a portal or gateway on the L1. 0xEDa034A4B7806e1283e99F8522eFd08d855B9b72 ProxyAdmin This contract is responsible for managing proxy contracts, allowing for upgrades and access control. 0x27a591Ec09AAfEEb39d7533AEf7C64E0305D1576 Proxy__OVM_L1CrossDomainMessenger This contract is a proxy for the L1CrossDomainMessenger contract on the Layer 2, enabling interaction with the Layer 2 contract from Layer 1. 0xd95D508f13f7029CCF0fb61984d5dfD11b879c4f Proxy__OVM_L1StandardBridge This is a proxy for the L1StandardBridge contract on the Layer 2 network, allowing interaction with the Layer 2 bridge from Layer 1. 0xF05F0e4362859c3331Cb9395CBC201E3Fa6757Ea SystemConfig This contract is responsible for managing system configurations, settings, or parameters in the protocol. 0x0be96fcB5eCCA87c775344fB76A3A1C6146cA5Fd SystemConfigProxy A proxy contract related to the SystemConfig contract, providing an interface or additional functionality. 0x7AC836148C14c74086D57F7828F2D065672Db3B8 SystemDictator This contract has a role in managing or governing certain aspects of the system or protocol. 0x0744F61646DdE7Bc2d2c18B13D08a8fba597666b SystemDictatorProxy A proxy contract related to the SystemDictator contract, providing an interface or additional functionality. 0xEb23CCD85eF040BdAf3CBf962C816cD9Cb691F35"},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#_3","title":"Protocol Addresses","text":""},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#l2-contract-addresses","title":"L2 Contract Addresses","text":"Name Description Address WBNB This contract represents Wrapped BNB, a token that is pegged to BNB on the opBNB network. 0x4200000000000000000000000000000000000006 L2CrossDomainMessenger This contract is responsible for facilitating cross-domain communication on Layer 2 of the opBNB network. 0x4200000000000000000000000000000000000007 L2StandardBridge This contract is a standard bridge on Layer 2, enabling the transfer of fungible tokens between different chains or networks. 0x4200000000000000000000000000000000000010 SequencerFeeVault This contract serves as a vault for collecting fees from sequencers, who are responsible for submitting transactions on opBNB. 0x4200000000000000000000000000000000000011 OptimismMintableERC20Factory This is a factory contract for creating mintable ERC-20 tokens on the Layer 2 network. 0x4200000000000000000000000000000000000012 GasPriceOracle This contract may provide gas price data to be used in transactions and fee calculations on the opBNB network. 0x420000000000000000000000000000000000000F L1Block This contract represents a block on Layer 1 in the context of interacting with opBNB. 0x4200000000000000000000000000000000000015 L2ToL1MessagePasser This contract is responsible for passing messages from Layer 2 to Layer 1 on the opBNB network. 0x4200000000000000000000000000000000000016 L2ERC721Bridge This contract is a bridge for transferring ERC-721 non-fungible tokens on Layer 2. 0x4200000000000000000000000000000000000014 OptimismMintableERC721Factory This is a factory contract for creating mintable ERC-721 tokens on the Layer 2 network. 0x4200000000000000000000000000000000000017 ProxyAdmin This contract is responsible for managing proxy contracts on the opBNB network, allowing for upgrades and access control. 0x4200000000000000000000000000000000000018 BaseFeeVault This contract acts as a vault for collecting base fees on the opBNB network. 0x4200000000000000000000000000000000000019 L1FeeVault This contract serves as a vault for collecting fees on Layer 1 in the context of interacting with opBNB. 0x420000000000000000000000000000000000001a"},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#reference","title":"reference","text":""},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/","title":"Optimizations on OP Stack - opBNB","text":"

    This document discusses the various optimizations made to OP Stack that enhances its performance and helps in offering super cheap gas fees.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#opbnb-offers-enhanced-performance-and-cheap-gas-fees","title":"opBNB offers enhanced performance and cheap gas fees","text":"

    opBNB enhances the performance of the \u201cExecution Layer\u201d and the \u201cDerivation Layer\u201d of the OP Stack as highlighted in OP Stack landscape.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#optimization-of-execution-layer","title":"Optimization of Execution Layer","text":"

    One of the main challenges in developing the opBNB protocol was to ensure a high throughput of transactions. To achieve this, opBNB leveraged execution optimization techniques that had previously been implemented for BSC.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#evm-state-data-access-optimization","title":"EVM State Data Access Optimization","text":"

    Before we dive into the details of the optimisations, let\u2019s see how EVM handles the state data. The diagram below illustrates how the EVM accesses state data. The EVM first checks the cache in memory for the data. If the data is not there, the EVM uses the LevelDB, which involves disk IO.

    By improving cache efficiency and accelerating database reads and writes, opBNB realizes substantial performance and scalability gains that benefit both node operators and end users.

    (Compared with standard Ethereum world state data storage model, BNB introduced the \u201cSharedPool\u201d as L1.5 cache to improve the hit rate of cache)

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#increased-accuracy-of-bloom-filter-in-l2-diff-layer","title":"Increased accuracy of Bloom Filter in L2: Diff Layer","text":"

    Avoiding unnecessary recursive accesses to cache by increasing the accuracy of Bloom Filter in L2: Diff Layer Bloom filters are a probabilistic data structure that can rapidly verify if an element exists within a data set. To access the state data, EVM uses the bloom filter to verify if the key-value pair is in the Diff Layer and then searches the cache recursively until it finds them, otherwise, EVM directly reads the data from the levelDB.

    However, bloom filters may yield false positives. Moreover, the rate of false positives increases as the dataset bloom filters evaluate expands. Given the opBNB dataset is larger than Ethereum\u2019s, the potential for false positives could be greater as well.

    The false positive can result in the unnecessary recursive access. To mitigate this, opBNB reduced the diff layer level from the default of 128 to a configurable parameter set at 32. This reduction decreases the size of the dataset, in turn diminishing the possibility of false positives to avoid the unnecessary time consuming operations to increase the efficiency of state retrieval.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#effective-prefetch-in-the-cache-model-of-l15-and-its-upper-layers","title":"Effective Prefetch in the cache model of L1.5 and its upper layers","text":"

    Prefetch is a technique that enhances the performance of transaction execution by loading data from disk to cache in advance. When a block needs to be processed in full sync mode or mined in mining mode, the opBNB node launches N threads to perform state prefetch.

    The threads execute the transactions of a block or TxPool and discard the results, but keep the data items in the cache. This way, when the node needs to access the data, it is more likely to find it in the cache rather than on disk, which improves the cache hit rate.

    However, the original prefetch design had a performance limitation. It used separate state databases for the prefetch and the main processes. The prefetch threads could only store the prefetched data in the L2 diff layer (See the 3 layer cache model that was explained before). To access this data, the main process had to traverse the L1, L2, and probably L3 layers, which was too slow for a high performance layer 2 chain.

    The new design improves performance by sharing a pool that holds the whole world state (originStorage) between the prefetch and the main EVM processes. This way, the prefetch threads can put the prefetched data right into the L1.5 (the upper layer of the cache model), which makes it faster for the main process to access. See the detailed process below.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#mining-process-optimization","title":"Mining Process Optimization","text":"

    The process of mining L2 blocks of OP Stack is illustrated in the diagram. It involves a loop where the Rollup Driver (opNode) imports the previous blocks and then invokes the Engine API (op-geth) to produce new blocks on Layer 2.

    The Rollup Driver (opNode) initiates the block generation process on op-geth by calling the engine_forkChoiceUpdatedv1 API of the Engine API(op-geth). This instructs Engine API(op-geth) to start producing an initial block by executing the transactions. (See \u201cEngine API: Initiate block production\u201d in the diagram). The Engine API(op-geth) then returns a payload ID to the Rollup Driver (opNode).

    However, when Engine API(op-geth) receives the engine_newPayloadV1 call from the Rollup Driver (opNode) to commit the block, it has to execute the transactions again, which is redundant and time-consuming. It can take hundreds of milliseconds to complete.

    To optimize the performance, we added a cache layer to store the execution results during the initial block production step. This way, when op-geth receives the engine_newPayloadV1 call, it can retrieve the data from the cache instead of executing the transactions again. This saves time and resources for the system.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#optimization-of-derivation-layer","title":"Optimization of Derivation Layer","text":"

    The batcher performance bottleneck was caused by the need to wait for 15 blocks (45 seconds) on Layer 1 (BSC) to confirm each batch of transactions before submitting the next one. This was due to the possibility of reorg on Layer 1 chain. To solve this problem, we introduced the asynchronous submission feature, which allows the batcher to submit batches without waiting for confirmation.

    A separate monitor process keeps track of Layer 1 and notifies the batcher if a reorg happens, so that the batcher can resubmit the affected transactions. This feature improves the efficiency of the batcher. It is not yet available on testnet and is still under development, but it will be deployed on opBNB mainnet.

    "},{"location":"bnb-opbnb/core-concepts/raas/","title":"Rollup as a Service (RaaS) on BNB Chain - opBNB","text":""},{"location":"bnb-opbnb/core-concepts/raas/#what-is-rollup-as-a-service","title":"What is Rollup as a Service","text":"

    Rollup-as-a-Service (RaaS) represents a transformative approach in the blockchain sphere, akin to Software-as-a-Service (SaaS) in the cloud computing domain, tailored specifically for decentralized applications (dApps) and blockchain projects. This innovative service model offers a cost-effective and efficient pathway for projects to build and deploy rollup networks.

    "},{"location":"bnb-opbnb/core-concepts/raas/#alignment-with-bnb-chains-roadmap-and-ecosystem-growth","title":"Alignment with BNB Chain\u2019s Roadmap and Ecosystem Growth","text":"

    The demand for RaaS within the BNB Chain ecosystem is not just a trend; it\u2019s a strategic response to the need for higher transaction throughput and enhanced scalability. As the chain eyes substantial growth, RaaS stands out as an essential service that supports this expansion. It does so by enabling developers to deploy scalable applications with ease, leveraging rollup technology to process transactions on Layer 2 network before finalizing them on the main blockchain(BSC).

    "},{"location":"bnb-opbnb/core-concepts/raas/#building-with-raas-aligned-with-bnb-chains-future","title":"Building with RaaS Aligned with BNB Chain\u2019s Future","text":"

    Building with Rollup as a Service (RaaS) on the BNB Chain involves leveraging specialized services from providers like NodeReal, AltLayer, Movement Labs, Lumoz, and 4everland, each offering unique tools to enhance blockchain application development. By adopting these specialized RaaS solutions, developers can leverage the strengths of the BNB Chain ecosystem to create innovative, reliable, and user-centric blockchain applications.

    Service Provider Developer tools and tech stack How to Start NodeReal E2E professional service with infrastructure support, including, indexing service, multi-sig wallet service, explorer, and other enterprise services. https://nodereal.io/semita Altlayer Versatile rollup-up stack support and no-code setup dashboard https://altlayer.io/ Movement Labs Move based L2 on BSC support https://movementlabs.xyz/ Lumoz Support zkevm on BSC https://lumoz.org/rollups 4EVERLAND One-click deplopyment of rollups on BSC https://docs.4everland.org/raas-beta/whats-rollups"},{"location":"bnb-opbnb/core-concepts/why-bsc-requires-opbnb/","title":"Why BSC Requires opBNB - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/why-bsc-requires-opbnb/#why-bsc-requires-opbnb","title":"Why BSC Requires opBNB","text":"

    Layer 1 networks are the base networks that provide the infrastructure for data transmission and validation, such as BSC and Ethereum. These networks face the challenge of network congestion during peak periods, which usually happens when any popular application runs a promotion campaign or experiences a spike in traffic. Network congestion can lead to high transaction fees, slow transactions, and poor user experience.

    To overcome these challenges, layer 1 networks need to improve their scalability, which is the ability to handle more transactions per second without compromising security. For example, BSC had a web3 game on BNB Smart Chain (BSC) in 2021 which generated over 8 million transactions per day.

    1. BSC\u2019s throughput capacity would presumably be vastly exceeded, resulting in slowed transaction speeds, delayed transaction finality, and a poor user experience both for game players and users of other dApps.

    2. Daily gas fees could potentially rise to over 6,800 BNB ($3M USD) at that level of usage, posing a substantial barrier to usability and sustainability of this game.

    The immense transaction loads from a dApp on such a large scale seem infeasible for BSC to handle efficiently in its current form. Significant optimizations and scaling solutions would likely be required for BSC to support such a dApp without network-wide performance degradation and unreasonably high costs.

    "},{"location":"bnb-opbnb/core-concepts/why-opstack/","title":"Why OP Stack - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/why-opstack/#why-op-stack-as-the-foundation-of-opbnb","title":"Why OP Stack as the Foundation of opBNB","text":"

    Our team had extensive discussions and research before we embarked on the mission of creating a high performance optimistic rollup for BNB Smart Chain.

    "},{"location":"bnb-opbnb/core-concepts/why-opstack/#our-goals","title":"Our goals:","text":"

    The OP Stack is a framework for building scalable and interoperable layer-2 solutions based on the utility, simplicity and extensibility principles. By choosing OP Stack as the bedrock of opBNB, we can achieve several benefits, such as:

    "},{"location":"bnb-opbnb/developers/bep20-crosschain/","title":"BEP20 Cross-chain - opBNB Develop","text":""},{"location":"bnb-opbnb/developers/bep20-crosschain/#arbitrary-bep20-cross-chain","title":"Arbitrary BEP20 Cross-chain","text":"

    You can use the opBNB bridge or third-party bridges like zkBridge and rhino.fi to easily deposit and withdraw most mainstream BEP20 tokens on BSC.

    If a token is not supported by these bridges, you have the option to deploy your own L2 mirror token contract on opBNB. This allows for permissionless cross-chain transfer of these tokens.

    This guide will help you deploy your L2 mirror token contract on opBNB and demonstrate how to use it for transferring tokens between BSC and opBNB.

    "},{"location":"bnb-opbnb/developers/bep20-crosschain/#deploying-a-l2-mirror-token-contract","title":"Deploying a L2 Mirror Token Contract","text":"

    There is a pre-deployed OptimismMintableERC20Factory contract on opBNB that allows you to deploy a L2 token by calling a function of the factory contract. The address of the contract is 0x4200000000000000000000000000000000000012.

    The function signature and the emitted event are as follows:

    /**\n    * @notice Emitted whenever a new OptimismMintableERC20 is created.\n    *\n    * @param localToken  Address of the created token on the local chain.\n    * @param remoteToken Address of the corresponding token on the remote chain.\n    * @param deployer    Address of the account that deployed the token.\n    */\nevent OptimismMintableERC20Created(\n    address indexed localToken,\n    address indexed remoteToken,\n    address deployer\n);\n\n/**\n    * @notice Creates an instance of the OptimismMintableERC20 contract.\n    *\n    * @param _remoteToken Address of the token on the remote chain.\n    * @param _name        ERC20 name.\n    * @param _symbol      ERC20 symbol.\n    *\n    * @return Address of the newly created token.\n    */\nfunction createOptimismMintableERC20(\n    address _remoteToken,\n    string memory _name,\n    string memory _symbol\n) public returns (address) {}\n

    _remoteToken is the address of the token on the remote chain, which is BSC in this case. _name and _symbol should be the same with the name and symbol of the token on BSC. The decimal of the token on opBNB is always 18.

    Here is the transaction that generates the FDUSD token on opBNB.

    Warning: It does not support certain BEP20 configurations: - Fee on transfer tokens - Tokens that modify balances without emitting a Transfer event

    "},{"location":"bnb-opbnb/developers/bep20-crosschain/#cross-chain-transfer-with-js-sdk","title":"Cross-chain Transfer with JS SDK","text":"

    Once you have deployed your own L2 mirror token contract, you can use the JS SDK to transfer tokens between BSC and opBNB.

    The following script is a TypeScript demo script. It uses ethers.js and @eth-optimism/sdk to transfer tokens between BSC and opBNB.

    You can save the script as erc20CrosschainTransfer.ts and run it with the following command(ensure that you have installed deno):

    deno run -A erc20CrosschainTransfer.ts\n

    Feel free to modify the script to suit your needs.

    import { Contract, ethers, Signer, Wallet } from \"npm:ethers@^5\";\nimport \"https://deno.land/x/dotenv/load.ts\";\nimport { CrossChainMessenger, ETHBridgeAdapter } from \"npm:@eth-optimism/sdk\";\nimport * as optimismSDK from \"npm:@eth-optimism/sdk\";\n\nconst gwei = BigInt(1e9);\nconst BridgeConfigTestnet = {\n  l1URL: \"https://bsc-testnet.bnbchain.org\",\n  l2URL: \"https://opbnb-testnet-rpc.bnbchain.org\",\n  l1ChainID: 97,\n  l2ChainID: 5611,\n  contracts: {\n    AddressManager: \"0x0000000000000000000000000000000000000000\",\n    StateCommitmentChain: \"0x0000000000000000000000000000000000000000\",\n    CanonicalTransactionChain: \"0x0000000000000000000000000000000000000000\",\n    BondManager: \"0x0000000000000000000000000000000000000000\",\n    L1CrossDomainMessenger: \"0xD506952e78eeCd5d4424B1990a0c99B1568E7c2C\",\n    L1StandardBridge: \"0x677311Fd2cCc511Bbc0f581E8d9a07B033D5E840\",\n    OptimismPortal: \"0x4386C8ABf2009aC0c263462Da568DD9d46e52a31\",\n    L2OutputOracle: \"0xFf2394Bb843012562f4349C6632a0EcB92fC8810\",\n  },\n  l1GasPrice: 5n * gwei,\n  l1Explorer: \"https://testnet.bscscan.com\",\n  l2Explorer: \"https://testnet.opbnbscan.com\",\n};\n\nconst BridgeConfigMainnet = {\n  l1URL: \"https://bsc-dataseed.bnbchain.org\",\n  l2URL: \"https://opbnb-mainnet-rpc.bnbchain.org\",\n  l1ChainID: 56,\n  l2ChainID: 204,\n  contracts: {\n    AddressManager: \"0x0000000000000000000000000000000000000000\",\n    StateCommitmentChain: \"0x0000000000000000000000000000000000000000\",\n    CanonicalTransactionChain: \"0x0000000000000000000000000000000000000000\",\n    BondManager: \"0x0000000000000000000000000000000000000000\",\n    L1CrossDomainMessenger: \"0xd95D508f13f7029CCF0fb61984d5dfD11b879c4f\",\n    L1StandardBridge: \"0xF05F0e4362859c3331Cb9395CBC201E3Fa6757Ea\",\n    OptimismPortal: \"0x7e2419F79c9546B9A0E292Fd36aC5005ffed5495\",\n    L2OutputOracle: \"0x0d61A015BAeF63f6740afF8294dAc278A494f6fA\",\n  },\n  l1GasPrice: 3n * gwei,\n  l1Explorer: \"https://bscscan.com\",\n  l2Explorer: \"https://opbnbscan.com\",\n};\n\nconst BridgeConfig = BridgeConfigTestnet;\n\nconst privateKey = Deno.env.get(\"PRIVATE_KEY\")!;\nconst l1RpcProvider = new ethers.providers.JsonRpcProvider(BridgeConfig.l1URL);\nconst l2RpcProvider = new ethers.providers.JsonRpcProvider(BridgeConfig.l2URL);\nconst wallet = new Wallet(privateKey);\nconst l1Signer = wallet.connect(l1RpcProvider);\nconst l2Signer = wallet.connect(l2RpcProvider);\nlet crossChainMessenger: CrossChainMessenger;\n\nconst l1BUSDAddr = \"0xeD24FC36d5Ee211Ea25A80239Fb8C4Cfd80f12Ee\";\nconst l2BUSDAddr = \"0xa9aD1484D9Bfb27adbc2bf50A6E495777CC8cFf2\";\n\nfunction setup() {\n  crossChainMessenger = new CrossChainMessenger({\n    l1ChainId: BridgeConfig.l1ChainID,\n    l2ChainId: BridgeConfig.l2ChainID,\n    l1SignerOrProvider: l1Signer,\n    l2SignerOrProvider: l2Signer,\n    bedrock: true,\n    contracts: {\n      l1: BridgeConfig.contracts,\n      l2: optimismSDK.DEFAULT_L2_CONTRACT_ADDRESSES,\n    },\n  });\n  const ethBridgeAdapter = new ETHBridgeAdapter(\n    {\n      messenger: crossChainMessenger,\n      l1Bridge: BridgeConfig.contracts.L1StandardBridge,\n      l2Bridge: \"0x4200000000000000000000000000000000000010\",\n    },\n  );\n  crossChainMessenger.bridges.ETH = ethBridgeAdapter;\n}\n\nasync function depositERC20() {\n  const tx = await crossChainMessenger.depositERC20(l1BUSDAddr, l2BUSDAddr, 1, {\n    overrides: {\n      gasPrice: BridgeConfig.l1GasPrice,\n    },\n  });\n  await tx.wait();\n  console.log(\n    `depositBNB Transaction hash (on L1): ${BridgeConfig.l1Explorer}/tx/${tx.hash}`,\n  );\n  console.log(\n    `please check ${BridgeConfig.l2Explorer}/address/${l1Signer.address}?tab=deposit&p=1 for the deposit txn on L2`,\n  );\n}\n\nasync function withdrawERC20(): Promise<string> {\n  const tx = await crossChainMessenger.withdrawERC20(\n    l1BUSDAddr,\n    l2BUSDAddr,\n    1,\n    {\n      overrides: {\n        maxPriorityFeePerGas: 1,\n        maxFeePerGas: 10000,\n      },\n    },\n  );\n  await tx.wait();\n  console.log(\n    `withdrawBNB Transaction hash (on L2): ${BridgeConfig.l2Explorer}/tx/${tx.hash}`,\n  );\n  return tx.hash;\n}\n\nasync function proveWithdrawal(hash: string, wait: boolean = true) {\n  while (true) {\n    try {\n      const tx = await crossChainMessenger.proveMessage(hash, {\n        overrides: {\n          gasPrice: BridgeConfig.l1GasPrice,\n        },\n      });\n      await tx.wait();\n      console.log(\n        `proveWithdrawal Transaction hash (on L1): ${BridgeConfig.l1Explorer}/tx/${tx.hash}`,\n      );\n      break;\n    } catch (error) {\n      console.log(error.message);\n      if (error.message.includes(\"state root for message not yet published\")) {\n        if (wait) {\n          console.log(\n            `Waiting for status to be READY_TO_PROVE, current time: ${new Date()}`,\n          );\n        } else {\n          throw error;\n        }\n      } else {\n        throw error;\n      }\n    }\n  }\n}\n\nasync function finalizeWithdrawal(hash: string, wait: boolean = true) {\n  while (true) {\n    try {\n      const tx = await crossChainMessenger.finalizeMessage(hash, {\n        overrides: {\n          gasPrice: BridgeConfig.l1GasPrice,\n        },\n      });\n      await tx.wait();\n      console.log(\n        `finalizeWithdrawal Transaction hash (on L1): ${BridgeConfig.l1Explorer}/tx/${tx.hash}`,\n      );\n      break;\n    } catch (error) {\n      if (\n        error.message.includes(\n          \"proven withdrawal finalization period has not elapsed\",\n        )\n      ) {\n        if (wait) {\n          console.log(\n            `Waiting for status to be READY_TO_FINALIZE, current time: ${new Date()}`,\n          );\n        } else {\n          throw error;\n        }\n      } else {\n        throw error;\n      }\n    }\n  }\n}\n\nasync function main() {\n  console.log(\"opbnbBridge demo\");\n\n  setup();\n  // deposit ERC20\n  await depositERC20()\n\n  // withdraw ERC20\n  const hash = await withdrawERC20();\n  await proveWithdrawal(hash);\n  await finalizeWithdrawal(hash);\n}\n\nawait main();\n
    "},{"location":"bnb-opbnb/developers/cheat-sheet/","title":"Hardware Requirements - opBNB Develop","text":""},{"location":"bnb-opbnb/developers/cheat-sheet/#hardware-requirements","title":"Hardware Requirements","text":"

    Setting up a node in the BNB Chain ecosystem requires understanding hardware requirements. The Minimum Hardware Requirement ensures efficient management of average transaction volumes, while the Recommended Hardware Requirement caters to high performance, capable of processing up to 100 million gas per second and handling 1k QPS (Query Per Second), ideal for heavy transaction loads or peak efficiency.

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#processor","title":"Processor","text":"

    CPU Type: Intel Xeon Scalable processors (Ice Lake) or newer

    op-node:

    op-geth:

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#memory","title":"Memory","text":"

    op-node:

    op-geth:

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#storage","title":"Storage","text":"

    op-node:

    op-geth:

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#network","title":"Network","text":""},{"location":"bnb-opbnb/developers/cheat-sheet/#running-your-own-opbnb-node","title":"Running Your Own opBNB Node","text":""},{"location":"bnb-opbnb/developers/cheat-sheet/#performance-stability-optimization","title":"Performance Stability Optimization","text":"

    L1 RPC Configuration:

    Configure multiple L1 RPC endpoints for op-node setups on L2 solutions like opBNB to ensure synchronization with the L1 chain, security, data integrity, and reduced risk of single point of failure.

    For example:

      export L1_RPC1=https://bsc-dataseed.bnbchain.org\n  export L1_RPC2=https://bsc.nodereal.io\n  --l1=rpc1,rpc2\u2026\n
    Optimize L1 receipt retrieval performance

    L2 Sync Mode Settings:

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#node-health-monitoring","title":"Node Health Monitoring","text":""},{"location":"bnb-opbnb/developers/cheat-sheet/#import-json-model","title":"Import JSON Model","text":"

    Monitor your node\u2019s health by importing the rpc_nodes.json model.

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#important-metrics","title":"Important Metrics","text":""},{"location":"bnb-opbnb/developers/developer-tools/","title":"Developer Tools - opBNB Develop","text":"

    One of our main objectives is to expand the adoption and utility of opBNB as a high performance and low cost Layer 2 chain on the BNB Smart Chain. To achieve this goal, we have to ensure that our underlying technology is robust, scalable and user-friendly. That is why we are committed to developing and improving the core infrastructure and tools that support opBNB and its community of users, hosts and developers. Below are the ecosystem we are building for the opBNB.

    "},{"location":"bnb-opbnb/developers/developer-tools/#summary","title":"Summary","text":"Categories Sub Categories Infrastructure and Toolings DAO Governance DAO Governance XDao,Snapshot Node Providers Node Provider NodeReal Explorer Explorer NodeReal opBNB Scan, BSCScan Developer Platforms Truffle, Foundry, Hardhat, Remix Use Access Tooling Wallet Binance Web3 Wallet, Metamask, TrustWallet, Particle Network, Gem Wallet, OKX Wallet, MathWallet, Sequence.build, Avatar, Openfort Bridges opBNB Bridge,PolyHedra, rhino.fi dApp Store dApp Bay Oracles Price Feeds, VRF Binance Oracle, Supra Storage Decentralized Storage BNB Greenfield Security AvengerDAO Account Abstraction Particle Network, Biconomy, CyberConnect, Openfort MultiSig BNB Chain Multi-Sig Wallet Data Analytics DefiLlama, CoinGecko, DappBay Indexing NodeReal\u2019s opBNB Graph QL NFT NFT Marketplace Element\u2019s NFT Marketplace"},{"location":"bnb-opbnb/developers/developer-tools/#binance-exchange-support","title":"Binance Exchange Support","text":"

    Binance has supported deposit and withdrawal on 7th Nov, 2023. The initial list is BNB, FDUSD, and USDT as a start.

    "},{"location":"bnb-opbnb/developers/developer-tools/#node-providers","title":"Node Providers","text":"

    Needless to mention that the stability of RPC nodes is crucial to any blockchain, in this instance BNB Chain has NodeReal who is one of opBNB early and core contributors to anchor this task.

    NodeReal RPC can be accessed through their API marketplace. For common/public nodes, communities can access BNB ChainList.

    "},{"location":"bnb-opbnb/developers/developer-tools/#wallet","title":"Wallet","text":"

    Crypto/Digital wallet serves as an entry point for users to access blockchain. opBNB have known wallets providing access to opBNB such as Metamask and Trustwallet, leading the front.

    On Account Abstraction(AA), CyberConnect, Particle Network, Biconomy, Openfort has already integrated with opBNB.

    MultiSig wallet BNB Chain has provided its own Safe Multi-Sig Wallet.

    "},{"location":"bnb-opbnb/developers/developer-tools/#wallet-as-a-servicewaas","title":"Wallet as a Service[WaaS]","text":"

    Wallet-as-a-Service (WaaS) streamlines the integration of digital wallets into applications, allowing businesses to manage cryptocurrencies and tokens effortlessly. By handling the complexities of wallet infrastructure, WaaS enables a secure and user-friendly experience for managing digital assets, fostering wider blockchain adoption and enhancing operational efficiency.

    Below wallet have supported Wallet-as-a-Service (WaaS) platforms on the BNB Smart Chain and opBNB, facilitating seamless integration of digital wallet functionalities into applications for managing opBNB and other assets.

    Project Name Main Website WaaS Document Particle Network https://particle.network/ https://particle.network/wallet-introduction.html Sequence.build https://sequence.xyz/ https://sequence.build/landing Avatar Wallet https://avatarwallet.io/ https://docs.avatarwallet.io/docs/introduction Openfort https://openfort.xyz/ https://openfort.xyz/docs ## Bridges

    For bridges opBNB has its own default bridge, which is built mirroring OP Stack. This also means that it has the 7 days challenge period, similar to OP bridge, BASE bridge. But opBNB does have 3rd party bridge providers, such as Polyhedra and Rhino.Fi that provide shorter withdrawal periods.

    "},{"location":"bnb-opbnb/developers/developer-tools/#data-analytics","title":"Data Analytics","text":"

    Several known industry platform already started supporting opBNB, i.e. DefiLlama , CoinGecko, DappBay. For listing on DappBay, projects can fill up this form.

    "},{"location":"bnb-opbnb/developers/developer-tools/#data-indexing","title":"Data Indexing","text":"

    opBNB currently has NodeReal\u2019s opBNB Graph QL as the initial support[Beta Version] as current players such as TheGraph have their pipeline full for the rest of the year. For projects needing such services, projects can liaise with NodeReal on specs, requirements. [Process Link]

    "},{"location":"bnb-opbnb/developers/developer-tools/#dao","title":"DAO","text":"

    Essential component as the BNB Chain moves towards decentralization. XDao and Snapshot are now supporting opBNB.

    "},{"location":"bnb-opbnb/developers/developer-tools/#for-defi-specific","title":"For DeFi Specific","text":""},{"location":"bnb-opbnb/developers/developer-tools/#oracle","title":"Oracle","text":"

    Binance Oracle has started supporting opBNB since Day1. Feel free to reach Binance Oracle for product support and demo.

    "},{"location":"bnb-opbnb/developers/developer-tools/#for-gamesocial-media","title":"For Game/Social Media","text":""},{"location":"bnb-opbnb/developers/developer-tools/#vrf","title":"VRF","text":"

    Binance Oracle has support for opBNB VRF. Feel free to reach Binance Oracle for product support and demo.

    "},{"location":"bnb-opbnb/developers/developer-tools/#nft-marketplace-minting","title":"NFT Marketplace & Minting","text":"

    Element\u2019s NFT Marketplace is already live on opBNB. Minting feature will be ready soon in Nov.

    "},{"location":"bnb-opbnb/developers/geth-sync/","title":"Geth P2P Sync - opBNB Develop","text":""},{"location":"bnb-opbnb/developers/geth-sync/#geth-p2p-sync-feature","title":"Geth P2P Sync Feature","text":"

    We\u2019re excited to introduce a new feature in this release: The Geth P2P Sync Feature. This feature significantly enhances the speed of block data synchronization by leveraging peer-to-peer syncing among geth nodes, as opposed to the previous method of deriving transactions from L1 for each synchronization.

    "},{"location":"bnb-opbnb/developers/geth-sync/#benefits-of-geth-p2p-sync-feature","title":"Benefits of Geth P2P Sync Feature","text":"

    The Geth P2P Sync Feature greatly accelerates block data synchronization. Our tests on the testnet have shown impressive results:

    These improvements can save considerable time and resources, thus improving the overall performance of your operations.

    "},{"location":"bnb-opbnb/developers/geth-sync/#configurations-for-geth-p2p-sync-feature","title":"Configurations for Geth P2P Sync Feature","text":""},{"location":"bnb-opbnb/developers/geth-sync/#new-configurations-op-node","title":"New Configurations (op-node)","text":"

    The above settings are essential for enabling the Geth P2P Sync Feature. Please ensure that these settings are correctly configured in your op-node.

    "},{"location":"bnb-opbnb/developers/geth-sync/#existing-configurations-op-geth","title":"Existing Configurations (op-geth)","text":"

    You can select either of the two options for the syncmode:

    1. full (Recommended): This mode performs a full sync and executes each block. The sync time has been significantly reduced with the new Geth P2P Sync Feature, taking about 15 hours on the testnet (latest height: 10 million).
    2. snap: This mode performs a snapshot sync, which does not execute transactions but still maintains data completeness. This mode is recommended when your P2P peer nodes are trustworthy. The sync time is about 1 hour on the testnet.

    For the bootnodes configuration, you can use the following geth bootnode nodes:

    Ensure the above configurations are correctly set up to fully benefit from the new Geth P2P Sync Feature in this release. We hope you find this feature advantageous. Your feedback is always welcome.

    "},{"location":"bnb-opbnb/developers/multisig-wallet/","title":"Multi-sig Wallet","text":""},{"location":"bnb-opbnb/developers/multisig-wallet/#bnb-chain-safe-multi-sig-wallet-service","title":"BNB Chain Safe Multi-Sig Wallet Service","text":"

    BNB Chain deployed a multi-sig wallet service based on the Gnosis Safe protocol on opBNB mainnet, opBNB testnet and BSC testnet. It provides users with a secure and convenient way to manage their digital assets and transactions.

    "},{"location":"bnb-opbnb/developers/multisig-wallet/#how-to-use-the-bnb-chain-multi-sig-wallet-service","title":"How to Use the BNB Chain Multi-Sig Wallet Service","text":"

    To use the BNB Chain multi-sig wallet service, connect with your own EOA wallet to start. Visit https://multisig.bnbchain.org/welcome

    Read the Safe Doc for details.

    "},{"location":"bnb-opbnb/developers/multisig-wallet/#safe-transaction-service-api","title":"Safe Transaction Service API","text":"

    To create or list safe transactions programmatically, use the Safe Transaction Service API. Here are the endpoints for the opBNB testnet and opBNB mainnet:

    Testnet: https://safe-transaction-opbnb-testnet.bnbchain.org/

    Mainnet: https://safe-transaction-opbnb-mainnet.bnbchain.org/

    Read the api-kit Doc for details.

    "},{"location":"bnb-opbnb/developers/network-faucet/","title":"Testnet Faucet - opBNB Develop","text":""},{"location":"bnb-opbnb/developers/network-faucet/#testnet-faucet","title":"Testnet Faucet","text":"

    If you want to test the functionality of the BNB Smart Chain, you will need some testing tokens, such as tBNB and other major tokens like USDC, BUSD, DAI, and wrapped Bitcoin. There are two ways to claim these testing tokens. Please refer to the BSC faucet doc for details. After you claim your tokens, you can transfer your testing assets to opBNB to start testing through testnet bridge.

    "},{"location":"bnb-opbnb/developers/quick-guide/","title":"Quick Guide - opBNB","text":"

    If you\u2019re a developer seeking to build on opBNB, you\u2019ve come to the right place. This document provides all the information you need to develop opBNB applications.

    "},{"location":"bnb-opbnb/developers/quick-guide/#getting-started","title":"Getting Started","text":"

    The opBNB network is the Layer 2 scaling solution for the BNB Smart Chain(BSC) powered by OP Stack.

    If you are brand new to opBNB, you can try start with the guide on creating a fullstack dapp on opBNB. It will familiarize you with the basic steps of deploying a smart contract on opBNB and interacting with it from a dapp.

    opBNB is EVM equivalent so you can feel confident that your existing Ethereum smart contract skills will transfer seamlessly to opBNB. There are a few small differences between Ethereum and opBNB, so make sure to be aware of them. You can refer to the optimism documentation for more information.

    "},{"location":"bnb-opbnb/developers/quick-guide/#connecting","title":"Connecting","text":"

    Here are some resources to help you get connected to the opBNB network:

    "},{"location":"bnb-opbnb/developers/quick-guide/#get-tokens","title":"Get Tokens","text":"

    opBNB is a Layer 2 on BSC, so tokens can be moved between the two chains using bridges. For the testnet, you can use the faucet to obtain some test tokens on BSC and then bridge them to opBNB using the official bridge. For the mainnet, you can bridge tokens from BSC to opBNB using various bridges, or you can withdraw tokens directly from a centralized exchange (CEX) which supports opBNB network(e.g. Binance).

    "},{"location":"bnb-opbnb/developers/quick-guide/#cross-chain-interoperability","title":"Cross-Chain Interoperability","text":"

    To build cross-chain applications between BSC and opBNB, you should understand how cross-chain message passing works. You can refer to the sending data between L1 and L2 guide for more information.

    "},{"location":"bnb-opbnb/developers/quick-guide/#developer-tools","title":"Developer Tools","text":"

    For more tools and details, you can refer to this doc.

    "},{"location":"bnb-opbnb/developers/set-gas-price/","title":"Set Gas Price - opBNB Develop","text":"

    This document shows you how to set the priority price and base price for opBNB transactions in wallet. These prices determine how much you are willing to pay for your transaction to be included in the next block (Priority Gas Price) and how much you are willing to pay for the gas used by your transaction. Setting these prices correctly can help you save money and avoid delays.

    To set the priority price and base price, follow these steps:

    Metamask:

    1. Open your metamask wallet and click on the opBNB network at the top right corner.

    2. Click on the send button and enter the recipient address and the amount of opBNB you want to send.

    3. Before you confirm your transaction, click on the advanced->edit button next to the gas fee section.

    4. You will see two sliders: one for the Max base fee(Gwei) price and one for the Priority Fee(Gwei). The priority price is the amount of opBNB you are willing to pay per unit of gas for your transaction to be included in the next block. The base price is the amount of opBNB you are willing to pay per unit of gas for the gas used by your transaction. The total gas fee is the sum of these two prices multiplied by the gas consumed. The base fee for opBNB transactions is dynamic and depends on the demand for block space. The minimum possible base fee is 0.000000008 gwei. The priority fee, which is paid to the sequencer who includes the transaction in a block, can also be as low as 0.000000001 gwei. However, these fees may vary depending on the network congestion and the urgency of the transaction.

    5. You can adjust the sliders according to your preferences. The higher the priority price, the faster your transaction will be confirmed, but the more expensive it will be. The lower the base price, the cheaper your transaction will be, but the more likely it will fail if the gas limit is too low.

    6. Once you are satisfied with your settings, click on save and then confirm your transaction.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/","title":"Build on opBNB - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-to-check-if-a-smart-contract-is-verified-on-opbnb-using-an-api-get-request","title":"How to check if a smart contract is verified on opBNB using an API GET request?","text":"

    With the API key and smart contract address, you can retrieve the contract\u2019s verification status, source code & ABI.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#why-does-token-info-like-name-symbol-is-not-displayed-on-opbnbscan-despite-having-contract-verified","title":"Why does token info (like name, symbol) is not displayed on opBNBscan despite having contract verified?","text":"

    If the deployed contract is a proxy contract, then the info. will not be displayed as opBNBscan uses enhanced API to fetch the token details like name, symbol etc. In this case, enhanced API needs to call the implementation contract to fetch the token details. Currently, this feature is under development where enhanced API will make call to implementation contract when token info. returned from proxy contract is empty.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-are-the-third-party-provider-services-where-we-can-purchase-private-rpc-access","title":"What are the third-party provider services where we can purchase private RPC access?","text":"

    You can purchase private RPC access from Nodereal.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#are-there-any-grants-or-financial-support-for-projects-on-opbnb","title":"Are there any grants or financial support for projects on opBNB?","text":"

    Yes, we provide the same support for opBNB as for BNB Smart Chain when it comes to grants or financing projects. Check here for the complete details.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#is-there-an-ability-to-run-nodes-on-opbnb","title":"Is there an ability to run nodes on opBNB?","text":"

    Check out the official documentation to learn how to run nodes on opBNB.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#can-a-native-project-on-opbnb-issues-its-token-natively-on-opbnb","title":"Can a native project on opBNB issues its token natively on opBNB?","text":"

    Yes, it is up to the project.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-is-the-recommended-approach-for-launching-projects-should-the-project-be-natively-launched-on-opbnb-and-then-bridged-to-l1-or-the-other-way-around","title":"What is the recommended approach for launching projects, should the project be natively launched on opBNB and then bridged to L1 or the other way around?","text":"

    The choice of L2 or L1 depends on the specific needs of the project. L2 offers better performance and lower cost, so it is advisable to use L2 as the starting point if these factors are important for the project.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#is-there-a-possibility-of-a-shared-sequencerliquidity-with-other-chains-built-on-opstack-in-the-future","title":"Is there a possibility of a shared sequencer/liquidity with other chains built on OPStack in the future?","text":"

    Unfortunately, no, in short term, this is BNB Chain team`s goal yet.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-programming-language-is-used-for-the-opbnb-chain-and-contracts","title":"What programming language is used for the opBNB chain and contracts?","text":"

    The pre-deployed smart contracts are written in Solidity, and opBNB is built with OP Stack framework. For details, please refer to official docs for more details.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#are-there-any-airdrops-for-opbnb","title":"Are there any airdrops for opBNB?","text":"

    We want to clarify that there is NO airdrop planned for opBNB as of now. Please be cautious and aware of any claims or messages suggesting otherwise. Protect yourself from potential scams by staying vigilant and verifying information from official sources.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-oracles-and-vrf-does-opbnb-support","title":"What oracles and VRF does opBNB support?","text":"

    opBNB is a permissionless chain that allows any VRF and oracle services to be integrated. The first two services that have been launched on opBNB are Binance Oracle and Polythera, which provide reliable and secure data feeds for smart contracts.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-to-do-if-there-is-trouble-verifying-smart-contract-with-all-available-methods-using-the-httpsopbnbscancomverifycontract","title":"What to do if there is trouble verifying smart contract with all available methods using the https://opbnbscan.com/verifyContract","text":"

    Try using the alternative explorer https://opbnb-testnet.bscscan.com/ for verifying your smart contracts.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-do-we-set-hardhat-verification-parameters-for-opbnb","title":"How do we set hardhat verification parameters for opBNB?","text":"

    Refer to the official Hardhat documentation here

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-does-opbnb-handle-the-storage-and-execution-of-metadata-associated-with-nfts-on-its-optimistic-rollup","title":"How does opBNB handle the storage and execution of metadata associated with NFTs on its optimistic rollup?","text":"

    The process of creating and storing NFTs on the opBNB is similar to other blockchains. You need to have a smart contract that defines the properties and functions of your NFT, and then deploy it on the opBNB. To store the metadata of your NFT, such as the name, description, image, and other attributes, you can use various storage solutions. Some examples are BNB Greenfield, IPFS, and Filecoin.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#why-my-opbnb-node-is-unable-to-catch-up-with-current-blocks","title":"Why my opBNB node is unable to catch up with current blocks?","text":"

    There is a possibility that the node\u2019s chain has been forked and is different from other nodes.

    In the event that the chain is forked due to a hard fork, it is recommended to reset the blockchain and synchronize it with the latest version of the program:

    1. Clear the data directory in OP Geth
    2. Update the opbnb to latest version: git clone -b v0.x.x git@github.com:bnb-chain/opbnb.git
    3. Update the op-geth to latest version: git clone -b v0.x.x git@github.com:bnb-chain/op-geth.git

    Follow the instructions here to re-sync the node. Just note that make sure to use the latest version of opbnb and op-geth, and use the new version genesis.json and rollup.json.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-to-verify-erc1967proxy-upgradeable-contract-on-opbnb-testnet-by-hardhat","title":"How to verify ERC1967Proxy upgradeable contract on opbnb-testnet by Hardhat?","text":"

    You can follow the instructions from How to verify a contract on Etherscan/BscScan/PolygonScan to use the solc-input.json to verify the proxy.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-to-get-proxys-constructor-arguments-for-verification","title":"How to get proxy\u2019s constructor arguments for verification?","text":"

    To form _data argument we need:

    1. Function name.
    2. Owner address + argument1 + argument2 + etc. Then copy \u201cEncoded data\u201d, add \u201c0x\u201d at the beginning of the text and past it as _data (Bytes) argument. For details, please refer to openzeppelin docs. An easier way is to look at the input data of the creation transaction for your proxy: https://testnet.opbnbscan.com/tx/0xa287b0b69472cb4961c528b16e799136a520f700b5407595314c3cdd0a21f8d6?tab=overview
    3. You can see that the encoded constructor arguments are at the last portion of the bytecode.
    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/","title":"Cross Chain - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/cross-chain-faqs/#how-does-opbnb-ensure-data-availability-and-security-for-off-chain-transactions","title":"How does opBNB ensure data availability and security for off-chain transactions?","text":"

    opBNB relies on a mechanism called \u201cfraud proofs\u201d to ensure data availability and security. Users can submit proofs on-chain that demonstrate any malicious behavior or incorrect transaction processing on the off-chain optimistic rollup. If a fraud proof is valid, the system can penalize the malicious actor and revert any incorrect state changes.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#who-is-responsible-for-gathering-and-bundling-off-chain-transactions-into-bundles-on-opbnb-network","title":"Who is responsible for gathering and bundling off-chain transactions into bundles on opBNB network?","text":"

    Sequencers are responsible for the aggregation of transactions, computation of the state transitions and submission of these to the rollup contract on BSC.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#what-is-the-role-of-the-aggregator-in-the-opbnb-network","title":"What is the role of the aggregator in the opBNB network?","text":"

    Aggregators are entities responsible for gathering and bundling off-chain transactions into batches. They play a crucial role in opBNB by forming these transaction batches and submitting them to the main BNB chain for validation. Aggregators also generate Merkle proofs for the data they submit, which are essential for the anchoring process.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#can-opbnb-handle-smart-contracts-and-complex-computations-like-the-main-bnb-chain","title":"Can opBNB handle smart contracts and complex computations like the main BNB Chain?","text":"

    The opBNB network is EVM compatible and works identically to BSC from a smart contract developer\u2019s perspective. This means that developers can easily deploy their existing Ethereum or BSC smart contracts on opBNB with minimal changes.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#how-does-opbnb-handle-cross-contract-interactions-and-composability","title":"How does opBNB handle cross-contract interactions and composability?","text":"

    Cross-contract interactions and composability are challenging aspects for optimistic rollups. While opBNB can facilitate cross-contract interactions, the limitations of off-chain processing mean that certain complex composability scenarios might be less efficient or not supported at all. Developers and projects using opBNB need to carefully consider these limitations when designing their applications.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#what-happens-if-theres-a-dispute-about-an-off-chain-transactions-validity","title":"What happens if there\u2019s a dispute about an off-chain transaction\u2019s validity?","text":"

    In the event of a dispute, a \u201cchallenge\u201d period is initiated. During this period, anyone can submit a fraud proof to challenge the validity of an off-chain transaction. If the fraud proof is valid and proves that the transaction was incorrect or malicious, the transaction is reverted on-chain, and the malicious actor might face penalties.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#can-smart-contracts-deployed-on-the-main-bnb-smart-chain-interact-seamlessly-with-applications-on-opbnb-if-yes-how","title":"Can smart contracts deployed on the main BNB Smart Chain interact seamlessly with applications on opBNB? If yes, how?","text":"

    Yes, this is achieved through a set of smart contracts that enable the execution of transactions on the opBNB network. The main contract is the batchInbox contract, which receives batches of transactions from the Sequencer on L1.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#how-to-allow-smart-contract-cross-chain-communication-between-l1-and-l2","title":"How to allow smart contract cross chain communication between L1 and L2?","text":"

    Directly interacting with smart contract functions that exist on L2(opBNB) from L1(BSC), is not possible as all smart contracts on L2 are isolated from L1.

    With that said, there is a way for developers to allow arbitrary message sending by writing their own contracts to build their required business logic. More details here.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#can-i-directly-transfer-assets-between-opbnb-and-greenfield","title":"Can I directly transfer assets between opBNB and Greenfield?","text":"

    Currently, direct cross-chain transfers between opBNB and Greenfield are not supported. However, users can achieve cross-chain transfers between these two networks by conducting a two-step process through the Binance Smart Chain (BSC). This involves transferring assets from opBNB to BSC and then from BSC to Greenfield.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/","title":"Gas and Fees - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#what-is-the-cost-of-transfer-transaction-on-opbnb-and-why-opbnb-hold-capacity-to-enable-the-mass-adoption-of-daily-small-amount-transactions","title":"What is the cost of transfer transaction on opBNB and why opBNB hold capacity to enable the mass adoption of daily small amount transactions?","text":"

    opBNB can make small daily transactions possible because the transaction fees are very low, around $0.005 per transaction. This is much lower than traditional payment methods like credit cards which charge around 1-3% per transaction. The low fees on opBNB make it economical for small purchases and daily transactions.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#what-is-the-link-to-the-canonical-bridge-for-gasstables","title":"What is the link to the canonical bridge for gas/stables?","text":""},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#where-can-we-get-the-token-pricing-for-the-bnb-token-on-opbnb","title":"Where can we get the token pricing for the BNB token on opBNB?","text":"

    You can get the token pricing for BNB on opBNB from Coinmarketcap

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#what-is-the-block-gas-limit-on-opbnb","title":"What is the block gas limit on opBNB?","text":"

    The block gas limit on opBNB is 100M/block, and the block time of opBNB is 1 second.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#how-are-transaction-fees-calculated-on-opbnb","title":"How are transaction fees calculated on opBNB?","text":"

    You can details about the transaction fee calculation from opBNB official docs

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#are-there-any-overheads-to-include-in-the-gas-calculation","title":"Are there any overheads to include in the gas calculation?","text":"

    Yes, there is a fixed overhead for L1 data fee is 2100, and dynamic_overhead(L1 Fee Scala) is 1.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#how-are-data-storage-fees-for-rollups-calculated","title":"How are data storage fees for rollups calculated?","text":"

    The data storage fees for rollups are calculated using the following formula.

    l1_data_fee = l1_gas_price * (tx_data_gas + fixed_overhead) * dynamic_overhead\n\nfixed_overhead = 2100\n\ndynamic_overhead = 1\n\ntx_data_gas = count_zero_bytes(tx_data) * 4 + count_non_zero_bytes(tx_data) * 16\n
    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#what-gas-fees-are-associated-with-withdrawing-opbnb-assets-from-the-main-chain-back-to-the-layer-2-network","title":"What gas fees are associated with withdrawing opBNB assets from the main chain back to the layer 2 network?","text":"

    Gas fees associated with withdrawing assets from the main chain back to the layer 2 network depend on the BNB chain\u2019s gas price at the time of withdrawal. These fees cover the cost of anchoring data on-chain and updating the network state.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#where-can-i-find-out-more-information-about-l2-gas-fees","title":"where can I find out more information about L2 gas fees?","text":"

    Prominent Layer 2 mainnet gas fees resource.

    To also check BNB Chain\u2019s Layer 1, BSC visit here.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#why-is-my-opbnb-transaction-rejected-or-pending","title":"Why is my opbnb transaction rejected or pending?","text":"

    There are several possible reasons why your transaction of opBNB may be rejected or pending. Here are some of the most common ones:

    To troubleshoot your transaction, you can do the following:

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#why-the-estimated-transaction-fee-is-zero-in-my-wallet","title":"Why the estimated transaction fee is zero in my wallet?","text":"

    It is because wallets are not well adapted to L2 networks. Wallets are designed for L1 networks, where the total transaction cost is calculated differently from L2 networks.

    For example, suppose you want to send some opBNB tokens on the opBNB network. When you use your wallet to approve the transaction, you will see that the estimated gas fee is 0BNB. This may seem like a great deal, but it is not the whole story.

    The gas fee you see in your wallet is based on the L2 part of the transaction, which is very low because it uses a batch processing technique to aggregate many transactions into one. The L2 part of the transaction consists of two components: the base fee and the priority fee. The base fee is a fixed amount that depends on the network congestion, and the priority fee is a variable amount that you can set to increase or decrease the speed of your transaction. For example, in our case, the base fee is 0.000000008 gwei and the priority fee is 0.00001 gwei, so the total L2 gas price is 0.000010008 gwei. The gas used is 21000, which is the standard amount for a transfer transaction. Therefore, the total L2 gas fee is 0.000010008 * 21000 = 0.210168 gwei, which is too small to be displayed in your wallet.

    However, this is not the only cost you have to pay for your transaction. There is also a layer 1 (L1) part of the transaction, which is the data cost. This is because every L2 transaction has to be recorded on the blockchain as data, and data storage on the blockchain is not free. The L1 part of the transaction depends on the size of the data and the L1 gas price at the time of submission. For example, in our case, the size of the data is 68 bytes and the L1 gas price is 249 gwei, so the total L1 gas fee is 68 * 249 = 16.932 gwei.

    Therefore, the actual cost of your transaction is the sum of the L2 and L1 parts, which is 0.210168 + 16.932 = 17.142168 gwei, or about 0.00001698 BNB, or about 0.003 USD at current prices. This is still very cheap compared to other blockchains, but it is not zero as your wallet shows.

    To verify this, you can check your transaction details on the opBNB explorer, where you will see both the L2 and L1 costs clearly displayed.

    We hope this helps you understand how opBNB works and why your wallet only shows the L2 cost.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#why-is-one-of-transactions-gas-fees-so-much-higher-than-the-rest","title":"Why is one of transaction\u2019s gas fees so much higher than the rest?","text":"

    A known issue that can cause irregularly high gas prices in opBNB transactions could be due to a high L1 gas price which is calculated by averaging block transaction gas prices using the formula: (Txn Fee = Gas Price * Gas + L1 Gas Price * L1 Gas Used * L1 Fee Scalar) This means that if there is an L1 block with an unusual high gas price, it will cause the gas price to be higher for a specific L2 block. This will be fixed going forward by introducing a static L1 gas price.

    "},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/","title":"opBNB Bridge - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/#what-is-the-status-of-the-integration-between-opbnb-and-optimisms-superchain","title":"What is the status of the integration between opBNB and Optimism\u2019s Superchain?","text":"

    opBNB is a project that aims to bring the benefits of L2 scaling and user-friendly UX to the BNB ecosystem. It will enable fast and cheap transactions on BNB L2, as well as smooth interoperability with Greenfield, a decentralized platform for building and running applications. Superchain is an innovative solution that leverages OP Stack to provide L2/L3 scaling and security for Ethereum. It allows users to access various L2 protocols with a single wallet and enjoy low fees and high throughput. opBNB is interested in collaborating with Superchain and integrating OP Stack into BNB Chain.

    "},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/#what-is-the-reason-for-the-discrepancy-in-the-estimated-cost-of-withdrawdeposit-transactions-between-the-opbnb-bridge-page-and-my-wallet","title":"What is the reason for the discrepancy in the estimated cost of withdraw/deposit transactions between the opBNB bridge page and my wallet?","text":"

    When you use the bridge to deposit or withdraw assets from opBNB, the bridge will estimate the gas cost for your transaction. This is done by simulating the execution of the transaction on the blockchain, without actually sending it or changing the state of the network. The simulation returns a number that indicates how much gas units the transaction would use if it was executed in the current network state.

    To get this number, the bridge uses a function called estimateGas, which implements a binary search algorithm between a lower and an upper bound of gas units. The lower bound is usually 21,000, which is the minimum gas required for a simple ether transfer. The upper bound is either specified by the user or derived from the block gas limit of the pending block. The function tries to execute the transaction with different gas values within this range until it finds the smallest gas value that does not cause an out-of-gas exception. This is the estimated gas usage of the transaction.

    For example: In this example, the bridge estimate of gas is around 0.0008 BNB, which is around $0.17.

    However, the wallet that you use to interact with the bridge may use a different method to calculate the estimated transaction cost. It may use the gas limit, which is the maximum amount of gas that you are willing to spend on the transaction. This is usually higher than the estimate given by the bridge.

    For example: The wallet estimate of the transaction is around 0.002 BNB, which is around $0.47.

    Once the transaction is executed on the chain, you can see the actual cost of the transaction in the opBNB explorer, which usually is similar to the estimate given by the bridge.

    "},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/#why-your-tokens-on-bsc-are-not-received-after-7-days-of-withdrawal-request","title":"Why your tokens on BSC are not received after 7 days of withdrawal request?","text":"

    You might have forgotten to sign the proof in the transaction history. This is a necessary step to initiate the 7 days challenge window. Without signing the proof, the bridge will not proceed with the challenge window and your withdrawal will be postponed.

    "},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/#why-do-i-need-to-sign-the-proof-to-start-the-7-days-challenge-window","title":"Why do I need to sign the proof to start the 7 days challenge window?","text":"

    When you withdraw tokens from opBNB to BSC, you need to provide a proof withdrawal to verify that your transaction on L2 is valid and consistent with the world state of L2. This is because L1 does not have access to the full world state of L2, only the data availability (DA) data and periodic snapshots of the world state from L2. The DA data is a compressed representation of the transactions on L2, which can be used to reconstruct the world state of L2 if needed. However, this process is expensive and time-consuming, so it is not done for every withdrawal. Instead, you need to submit a proof withdrawal, which is a cryptographic proof that your transaction on L2 matches the world state of L2 at a certain point in time. This way, you can ensure that your withdrawal is secure and accurate, and that no one can cheat or double-spend on L2.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/","title":"Protocol FAQs - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-achieve-high-performance-and-cheap-gas-fees","title":"How does opBNB achieve high performance and cheap gas fees?","text":"

    opBNB testnet enhances the performance of the \u201cExecution Layer\u201d and the \u201cDerivation Layer\u201d of the OP Stack as highlighted in OP Stack landscape.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-do-you-expect-the-tps-of-the-opbnb","title":"How do you expect the TPS of the opBNB?","text":"

    The TPS of opBNB can be estimated to be around 4,761 transactions per second based on the calculations. This is significantly higher than Ethereum\u2019s current TPS and can enable more frequent daily transactions.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-impact-opbnb-can-bring-to-web3-games","title":"What impact opBNB can bring to web3 games?","text":"

    Performance is important for games because gamers expect a highly responsive experience. Any lag, delay or choppiness can hamper enjoyment and immersion in the game. For blockchain games, fast transaction speeds and throughput are crucial to enable a seamless user experience. Gamers expect in-game assets and currencies to be transferred instantly, so the underlying blockchain network must be high performance

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-is-the-difference-between-opbnb-and-other-optimism-based-layer-2-solution-like-base","title":"What is the difference between opBNB and other Optimism based layer 2 solution, like Base?","text":"

    opBNB is the first layer 2 optimistic rollup on BSC, and BSC layer 1 cost is much lower than ETH, so the cost of layer 2 on BSC will give application developers a more affordable solution. Another difference is the opBNB will include the performance optimization techniques that have been used in BSC to have a much better performance.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#we-already-have-the-zkbnb-as-a-scaling-solution-why-opbnb-is-needed","title":"We already have the zkBNB as a scaling solution, why opBNB is needed?","text":"

    zkBNB is not EVM-comptatible, which means it is more suitable for NFT and token transactions, not for generic dApps. opBNB`s programmability is to support applications that need more flexibility.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#is-opbnb-connected-to-the-superchain-or-is-unrelated-can-opbnb-be-considered-as-just-optimistic-rollups-on-the-bnb-smart-chain","title":"Is opBNB connected to the superchain or is unrelated? Can opBNB be considered as just optimistic rollups on the BNB Smart Chain?","text":"

    opBNB can be considered as just rollups on BSC, not superchain. Please check this blog for more details. We may expand opBNB to superchain or L3 in the future.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-are-the-differences-between-opbnb-the-op-stack-and-arbitrum-orbit-what-are-the-pros-and-cons-of-these-different-tech-stacks","title":"What are the differences between opBNB, the OP Stack, and Arbitrum Orbit? What are the pros and cons of these different tech stacks?","text":"

    Check this blog for more details on the differences between opBNB, the OP Stack, and Arbitrum Orbit.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#why-op-stack-is-used-for-the-implementation-of-opbnb-instead-of-zkevm","title":"Why OP Stack is used for the implementation of opBNB instead of zkEVM?","text":"

    OP Stack is a reliable and robust solution that has been verified through rigorous testing. OP Stack is designed with modularity in mind, allowing it to support multiple clients and different data access layers without affecting other parts of the code. opBNB leverages OP Stack as a solid foundation to explore various ways to lower the cost and enhance the user experience.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#are-transactions-nonce-order-enforced","title":"Are transactions nonce-order enforced?","text":"

    Yes, on opBNB transactions, nonce-order enforced.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-prevent-front-running-and-other-transaction-related-attacks","title":"How does opBNB prevent front-running and other transaction-related attacks?","text":"

    Front-running and other transaction-related attacks are challenges faced by many blockchain systems. opBNB uses mechanisms like transaction ordering and timestamping to mitigate these attacks. Aggregators are incentivized to order transactions fairly and not prioritize their own transactions, reducing the potential for front-running.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#can-i-run-my-own-validator-or-aggregator-node-on-the-opbnb-network","title":"Can I run my own validator or aggregator node on the opBNB network?","text":"

    The opBNB network currently does not support running validator or aggregator nodes by individual users. However, we are working on this feature and plan to release it in the future. Please keep following opBNB for the latest updates.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-handle-reentrancy-attacks-within-its-optimistic-rollup-framework","title":"How does opBNB handle reentrancy attacks within its optimistic rollup framework?","text":"

    opBNB employs a combination of security measures, including strict transaction ordering and careful state management, to prevent reentrancy attacks. By enforcing a controlled and deterministic execution order, reentrancy attacks are mitigated.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#whats-the-mechanism-for-preventing-long-range-attacks-on-the-opbnb-network","title":"What\u2019s the mechanism for preventing long-range attacks on the opBNB network?","text":"

    opBNB implements a checkpointing mechanism that anchors its state onto the main BNB chain. This helps prevent long-range attacks by ensuring that the latest valid state is preserved on-chain, making any attempted reorganizations infeasible.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-ensure-the-ordering-of-transactions-in-a-decentralized-manner-without-central-coordination","title":"How does opBNB ensure the ordering of transactions in a decentralized manner without central coordination?","text":"

    The opBNB team is responsible for operating the sequencer, which ensures the correct order of transactions on the network. The sequencer is a centralized component that provides a reliable and efficient service for the users.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-handle-disputes-arising-from-cases-where-the-fraud-proof-itself-is-malicious-or-incorrect","title":"How does opBNB handle disputes arising from cases where the fraud proof itself is malicious or incorrect?","text":"

    opBNB employs a challenge mechanism to resolve disputes. If a malicious fraud proof is submitted, honest participants can submit counter-fraud proofs to correct the situation. The challenge period provides time for these proofs to be evaluated.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-is-the-challenge-period-on-opbnb","title":"What is the challenge period on opBNB?","text":"

    During the challenge period, any participant on the blockchain can raise challenges against the validity of the transactions or the execution results provided by the L2 sequencer. This mechanism is crucial for ensuring the integrity and correctness of the L2 execution.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-is-the-difference-between-validity-proof-and-fraud-proof","title":"What is the difference between validity proof and fraud proof?","text":"

    The validity proof is efficient at verifying, verifiers just need to check the \u201cproof\u201d once and confirm the correctness, but the disadvantage is that it is hard to generate the proof, both in algorithm and in efficiency. A popular validity proof solution is zero knowledge proof. On the other hand, the fraud proof is efficient at execution since it doesn\u2019t generate any proof at execution time, but the shorthand is that a specific time window must be established for participants to challenge the correctness of the L2 state, which will highly affect the finality of the L2 results.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-is-the-duration-of-the-challenge-period","title":"What is the duration of the challenge period?","text":"

    The challenge window is shorter on the testnet of opBNB, so you can test the withdrawal process faster. On the mainnet of opBNB, the challenge window will be 7 days long. 21. What are the penalties for dishonest sequencers? In case a sequencer is proven to be dishonest or provides incorrect execution results, penalties are applied. The sequencer\u2019s bond may be slashed as a form of punishment. Additionally, the state roots from the problematic transaction onwards will be erased and re-computed to ensure accuracy.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-to-check-if-a-smart-contract-is-verified-on-opbnb-using-an-api-get-request","title":"How to check if a smart contract is verified on opBNB using an API GET request?","text":"

    With the API key and smart contract address, you can retrieve the contract\u2019s verification status, source code & ABI.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-to-get-the-finalized-block-height-on-opbnb-and-why-is-it-always-hundreds-blocks-behind-the-latest","title":"How to get the finalized block height on opBNB and why is it always hundreds blocks behind the latest?","text":"

    The difference between latest and finalized by more than 200 blocks is expected. This is the concept in the OP design. The latest is defined as the latest unsafe block. The finalized means that the L2 block has been committed to L1 and the corresponding L1 block is finalized (by fast finality or natural finality).

    "},{"location":"bnb-opbnb/get-started/deposit-to-opbnb/","title":"Deposit BNB to opBNB - opBNB","text":""},{"location":"bnb-opbnb/get-started/deposit-to-opbnb/#deposit-bnbtbnb-to-opbnb","title":"Deposit BNB(tBNB) to opBNB","text":"

    Before building or deploying any applications on the opBNB network, you must first deposit BNB(tBNB) as your gas token from BNB Smart Chain to opBNB. You can do this using the opBNB bridge dApp(Testnet) or opBNB bridge dApp(Mainnet).

    Follow these steps to deposit tokens from BNB Smart Chain to opBNB:

    1. Make sure you have BNB(tBNB) tokens in your wallet on the BNB Smart Chain.
    2. In your wallet, switch your network to BNB Smart Chain. This is the Layer 1 network where your tokens currently are.
    3. Enter the amount of BNB(tBNB) you want to deposit to the opBNB network.
    4. Click \u201cDeposit\u201d to begin the transfer.
    5. Your wallet will prompt you to confirm the transaction. Click \u201cConfirm\u201d to sign it and pay the required gas fee.
    6. Once the transaction is processed, switch your network in your wallet to opBNB. The BNB amount you have deposited will appear in your wallet.
    7. You can now build, deploy, and interact with dApps on the opBNB network using the BNB(tBNB) you deposited. To withdraw tokens from opBNB back to BNB Smart Chain, simply go to the bridge, enter the amount to withdraw, and confirm the transaction. The bridge will transfer your tokens from the opBNB network back to the BNB Smart Chain testnet.

    "},{"location":"bnb-opbnb/get-started/deposit-to-opbnb/#opbnb-bridge-supported-tokens","title":"opBNB Bridge Supported Tokens","text":"

    The opBNB bridge supports you to transfer your assets from BSC to opBNB. The bridge supports most of the popular tokens, including BEP-20 tokens and wrapped bitcoin. If you want to test your applications that require these tokens, you can use the opBNB bridge to deposit and withdraw them in a simple and convenient way.

    The bridge page also provides a faucet link that allows you to claim these tokens from the faucet directly. To begin, simply click on the faucet link on the bridge page.

    "},{"location":"bnb-opbnb/get-started/network-info/","title":"Network Information - opBNB","text":""},{"location":"bnb-opbnb/get-started/network-info/#network-information","title":"Network Information","text":"Name Value Network Name opBNB Description The Layer 2 network of BNB Smart Chain. RPC Endpoint See here Chain ID 5611(Testnet), 204(Mainnet) Currency Symbol tBNB(Testnet) BNB(Mainnet) Block Explorer https://testnet.opbnbscan.com, https://opbnbscan.com, https://opbnb.bscscan.com/ Bridge https://opbnb-testnet-bridge.bnbchain.org, https://opbnb-bridge.bnbchain.org"},{"location":"bnb-opbnb/get-started/network-info/#rpc-endpoints","title":"RPC Endpoints","text":"

    You can use either public and private RPC endpoints to access opBNB.

    "},{"location":"bnb-opbnb/get-started/network-info/#public-testnet-rpc-endpointswss-is-supported","title":"Public Testnet RPC Endpoints(WSS is supported)","text":""},{"location":"bnb-opbnb/get-started/network-info/#public-mainnet-rpc-endpointswss-is-supported","title":"Public Mainnet RPC Endpoints(WSS is supported)","text":""},{"location":"bnb-opbnb/get-started/network-info/#private-opbnb-rpc-endpoints","title":"Private opBNB RPC Endpoints","text":"

    NodeReal supports the opBNB network, you can create your free opBNB RPC endpoints with your github or discord.

    To use the above private RPC endpoint, make sure to login to MegaNode service and create your private endpoints.

    "},{"location":"bnb-opbnb/get-started/wallet-configuration/","title":"Wallet Configuration - opBNB","text":""},{"location":"bnb-opbnb/get-started/wallet-configuration/#wallet-configuration","title":"Wallet configuration","text":"

    You can use any Ethereum or BSC wallet with opBNB. For instance, I will show you how to set up Metamask and Trustwallet for opBNB.

    To configure your wallet to work with opBNB, you will need to add both the BNB smart chain(Layer 1) and the opBNB network(Layer 2). Follow these steps:

    1. Add the BNB smart chain to your wallet. This is the Layer 1 blockchain that opBNB is built on top of.

    Testnet

    Mainnet

    Testnet

    Mainnet

    "},{"location":"bnb-opbnb/get-started/wallet-configuration/#references-how-to-configure-trustwallet-or-metamask","title":"References - How to configure Trustwallet or Metamask","text":"

    Trustwallet

    After you install the Trustwallet in your browser, you can go to settings->network.

    Select add custom network and enter the network information I mentioned above.

    Metamask

    After you install the metamask in your browser, you can go to settings -> networks -> add network page.

    Select add manual network and enter the network information.

    Depending on your location and preference, you can choose from a variety of RPC endpoints for BSC and opBNB. For more information about the endpoints and their features, please refer to the network information document that we have prepared for you. To ensure the best performance and user experience, you can test the latency of each endpoint before you configure it with your wallet.

    "},{"location":"bnb-opbnb/get-started/withdraw-from-opbnb/","title":"Withdrawal - opBNB","text":"

    To transfer your tokens from opBNB to BSC, you can use the opBNB bridge dApp(Testnet) or opBNB bridge dApp(Mainnet). Users who do not want to wait 7 days to claim their tokens can use a community bridge, but please note that community bridges may not be as secure as the official opBNB bridge.

    Note that the default option is the community bridge. To use the opBNB bridge, switch to the \u201cofficial bridge\u201d tab.

    "},{"location":"bnb-opbnb/get-started/withdraw-from-opbnb/#steps-of-withdrawal-through-official-bridge","title":"Steps of withdrawal through official bridge","text":"

    For users who choose the official opBNB bridge, you will need to wait for a challenge period of 7 days before you can claim your tokens on BSC. This challenge period is a security measure to prevent fraud and theft. The challenge period is necessary to ensure the security of the opBNB network and users. However, it can be inconvenient for users who need their tokens quickly. If you need your tokens immediately, you may want to consider using a community bridge instead. However, please be aware that community bridges may not be as secure as the official opBNB bridge. Do your research first.

    There are 2 steps after you submit your withdrawal request.

    1. Submit Proof: When you withdraw your tokens, they will be transferred from the opBNB network to the BSC network. After you submit the withdrawal request, your withdrawal status will change to Waiting for Proof, which indicates that the transaction is pending for the proof submission. You need to submit the proof manually.

    2. Claim Token: After you submit your proof, you need to wait until the transaction is ready to be collected after the challenge window, which is 7 days. The challenge window is a period of time during which anyone can challenge the validity of the transaction. If no one challenges the transaction, it will be finalized and you can collect your tokens on the BSC network.

    "},{"location":"bnb-opbnb/get-started/withdraw-from-opbnb/#third-party-bridges","title":"Third-party Bridges","text":"

    There are also third-party bridges with shorter withdrawal time.

    "},{"location":"bnb-smart-chain/","title":"BNB Smart Chain","text":"BNB Smart Chain

    BNB Smart Chain is a high-performance blockchain platform designed to enable the development of scalable and user-friendly decentralized applications (DApps), particularly in the decentralized finance (DeFi) space.

    Developers

    User guide to get started on BNB Smart Chain

    Staking

    BSC operates on a Proof-of-Staked-Authority (PoSA) blockchain

    Governance

    BSC is a community-oriented ecosystem, meticulously built upon the foundation of decentralized governance.

    Validator

    Validators secure the network based on the POSA consensus algorithm.

    Slashing

    Slashing is a component of on-chain governance that penalizes malicious or negative actions.

    BSC Ecosystem

    BSC ecosystem and developer tools

    Run a Node

    Run a BSC node

    MEV Builder

    Become a builder and create blocks and offering them to the validator

    JSON-RPC API

    Interacting with BSC requires sending requests to specific JSON-RPC API methods.

    "},{"location":"bnb-smart-chain/introduction/","title":"Introduction - BSC Develop","text":""},{"location":"bnb-smart-chain/introduction/#introduction","title":"Introduction","text":"

    BNB Smart Chain is an innovative solution to bring programmability and interoperability to BNB Beacon Chain. BNB Smart Chain relies on a system of 55 validators with Proof of Staked Authority (PoSA) consensus that can support short block time and lower fees. The most bonded validator candidates of staking will become validators and produce blocks. The double-sign detection, malicious vote detection and other slashing logic guarantee security, stability, and chain finality. Other than the 32 active validators, BSC will introduce more validators, e.g. another 23 inactive validators, into the validator set as backups, which will be called \u201cCandidates\u201d.

    Candidates will produce blocks and charge gas fees in BSC mainnet, but in a much less chance than the official validator set of 32 elected. The unavailable candidates will be slashed as well though in a smaller size. A decent motivation is expected to be maintained so that the candidate validators are willing to ensure the quality and help secure BSC.

    In an extreme case, if a majority of the active 32 validators get attacked and offline, Candidate Validators can report to BNB Beacon Chain about the stale blocking, resume it and eventually propose a re-election of the active validator set.

    The BNB Smart Chain also supports EVM-compatible smart contracts and protocols. Cross-chain transfer and other communication are possible due to native support of interoperability. The BNB Smart Chain will be:

    "},{"location":"bnb-smart-chain/introduction/#proof-of-staked-authority","title":"Proof of Staked Authority","text":"

    Although Proof-of-Work (PoW) has been recognized as a practical mechanism to implement a decentralized network, it is not friendly to the environment and also requires a large size of participants to maintain the security.

    Ethereum and some other blockchain networks, such as MATIC Bor, TOMOChain, GoChain, xDAI, do use Proof-of-Authority(PoA) or its variants in different scenarios, including both testnet and mainnet. PoA provides some defense to 51% attack, with improved efficiency and tolerance to certain levels of Byzantine players (malicious or hacked). It serves as an easy choice to pick as the fundamentals.

    Meanwhile, the PoA protocol is most criticized for being not as decentralized as PoW, as the validators, i.e. the nodes that take turns to produce blocks, have all the authorities and are prone to corruption and security attacks. Other blockchains, such as EOS and Lisk both, introduce different types of Delegated Proof of Stake (DPoS) to allow the token holders to vote and elect the validator set. It increases the decentralization and favors community governance.

    BSC here proposes to combine DPoS and PoA for consensus, so that:

    1. Blocks are produced by a limited set of validators
    2. Validators take turns to produce blocks in a PoA manner, similar to Ethereum\u2019s Clique consensus design
    3. Validator set are elected in and out based on a staking based governance

    Fast finalization can greatly improve user experience. The Fast Finality feature will be enabled upon the coming Plato upgrade. This will be a major advantage of BSC, and many dapps will benefit from it.

    The consensus protocol of BSC fulfills the following goals:

    1. Short Blocking time, 3 seconds on mainnet.
    2. It requires quite short time to confirm the finality of transactions, around 6s for mainnet after the coming Plato upgrade.
    3. There is no inflation of native token: BNB, the block reward is collected from transaction fees, and it will be paid in BNB.
    4. It is 100% compatible with Ethereum system.
    5. It allows modern proof-of-stake blockchain network governance.
    "},{"location":"bnb-smart-chain/introduction/#security","title":"Security","text":"

    Given there are more than \u00bd*N+1 validators are honest, PoA based networks usually work securely and properly. However, there are still cases where certain amount Byzantine validators may still manage to attack the network, e.g. through the Clone Attack. BSC does introduce Slashing logic to penalize Byzantine validators for double signing or inavailability. This Slashing logic will expose the malicious validators in a very short time and make the \u201cClone Attack\u201d very hard or extremely non-beneficial to execute.

    "},{"location":"bnb-smart-chain/introduction/#fast-finality","title":"Fast Finality","text":"

    Finality is critical for blockchain security, once the block is finalized, it wouldn\u2019t be reverted anymore. The fast finality feature is very useful, the users can make sure they get the accurate information from the latest finalized block, then they can decide what to do next instantly. More details of design, please to refer BEP-126

    Before the coming Plato upgrade,to secure as much as BC, BSC users are encouraged to wait until receiving blocks sealed by more than \u2154*N+1 different validators. In that way, the BSC can be trusted at a similar security level to BC and can tolerate less than \u2153*N Byzantine validators.With 21 validators, if the block time is 3 seconds, the \u2154*N+1 different validator seals will need a time period of (\u2154*21+1)*3 = 45 seconds. Any critical applications for BSC may have to wait for \u2154*N+1 to ensure a relatively secure finality. With above enhancement by slashing mechanism, \u00bd*N+1 or even fewer blocks are enough as confirmation for most transactions.

    After the coming Plato upgrade, the feature Fast Finality will be enabled. The chain will be finalized within two blocks if \u2154*N or more validators vote normally, otherwise the chain has a fixed number of blocks to reach probabilistic finality as before.

    "},{"location":"bnb-smart-chain/introduction/#reward","title":"Reward","text":"

    All the BSC validators in the current validator set will be rewarded with transaction fees in BNB. As BNB is not an inflationary token, there will be no mining rewards as what Bitcoin and Ethereum network generate, and the gas fee is the major reward for validators. After the coming Plato upgrade, part of the fees collected will be used as reward for finality voting. As BNB is also utility tokens with other use cases, delegators and validators will still enjoy other benefits of holding BNB.

    The reward for validators is the fees collected from transactions in each block. Validators can decide how much to give back to the delegators who stake their BNB to them, in order to attract more staking. Every validator will take turns to produce the blocks in the same probability (if they stick to 100% liveness), thus, in the long run, all the stable validators may get a similar size of the reward. Meanwhile, the stakes on each validator may be different, so this brings a counter-intuitive situation that more users trust and delegate to one validator, they potentially get less reward. So rational delegators will tend to delegate to the one with fewer stakes as long as the validator is still trustful (insecure validator may bring slashable risk). In the end, the stakes on all the validators will have less variation. This will actually prevent the stake concentration and \u201cwinner wins forever\u201d problem seen on some other networks.

    "},{"location":"bnb-smart-chain/introduction/#token-economy","title":"Token Economy","text":"

    BC and BSC share the same token universe for BNB and BEP2 tokens. This defines:

    1. The same token can circulate on both networks, and flow between them bi-directionally via a cross-chain communication mechanism.
    2. The total circulation of the same token should be managed across the two networks, i.e. the total effective supply of a token should be the sum of the token\u2019s total effective supply on both BSC and BC.
    3. The tokens can be initially created on BSC in a similar format as ERC20 token standard, or on BC as a BEP2, then created on the other. There are native ways on both networks to link the two and secure the total supply of the token.
    "},{"location":"bnb-smart-chain/introduction/#staking-and-governance","title":"Staking and Governance","text":"

    Proof of Staked Authority brings in decentralization and community involvement. Its core logic can be summarized as the below. You may see similar ideas from other networks, especially Cosmos and EOS.

    1. Token holders, including the validators, can put their tokens \u201cbonded\u201d into the stake. Token holders can delegate their tokens onto any validator or validator candidate, to expect it can become an actual validator, and later they can choose a different validator or candidate to re-delegate their tokens.
    2. All validator candidates will be ranked by the number of bonded tokens on them, and the top ones will become the real validators.
    3. Validators can share (part of) their blocking reward with their delegators.
    4. Validators can suffer from \u201cSlashing\u201d, a punishment for their bad behaviors, such as double sign and/or instability.
    5. There is an \u201cunbonding period\u201d for validators and delegators so that the system makes sure the tokens remain bonded when bad behaviors are caught, the responsible will get slashed during this period.
    "},{"location":"bnb-smart-chain/overview/","title":"Overview - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/overview/#bnb-smart-chain-high-performance-defi-hub","title":"BNB Smart Chain - High Performance DeFi Hub","text":"

    BNB Smart Chain (BSC) is a high-performance blockchain network. Officially launched on September 1, 2020, BSC is designed to enhance the functionality of the BNB Chain and facilitate the development and interaction of decentralized applications (DApps), decentralized finance (DeFi) platforms, and other blockchain-based innovations.

    "},{"location":"bnb-smart-chain/overview/#key-features-and-advantages","title":"Key Features and Advantages","text":"
    1. Ethereum Virtual Machine (EVM) Compatibility: BSC is fully compatible with the Ethereum Virtual Machine (EVM), enabling developers to port their Ethereum-based DApps and DeFi projects to BSC with minimal modifications. This compatibility extends to the use of popular Ethereum tools and applications, such as MetaMask, Truffle, and Remix.

    2. Low Transaction Fees and Fast Block Times: One of BSC\u2019s primary advantages is its low transaction fees. As of early 2024, the average transaction fee on BSC is around $0.10, significantly lower compared to Ethereum\u2019s average fee of \\(10-\\)20 during periods of high network congestion. Additionally, BSC block time of approximately is 3 seconds, ensuring rapid transaction confirmations and an overall smoother user experience.

    3. Robust Ecosystem and Growing Adoption: Since its inception, BSC has seen rapid growth in its ecosystem. By May 2024, BSC supports over 1,500 DApps, with popular platforms such as PancakeSwap, Venus, and BakerySwap leading the charge. The total value locked (TVL) in BSC-based DeFi protocols exceeds $20 billion, reflecting its substantial market adoption and user trust.

    "},{"location":"bnb-smart-chain/overview/#role-of-bnb","title":"Role of BNB","text":"

    BNB is the native utility token of both BNB Chain and BNB Smart Chain. Within the BSC ecosystem, BNB is used for various purposes:

    "},{"location":"bnb-smart-chain/overview/#future-prospects","title":"Future Prospects","text":"

    BNB Smart Chain is positioned as a significant player in the blockchain space, particularly in the realm of DeFi and DApps. With its emphasis on high performance, affordability, and interoperability, BSC aims to address some of the most pressing challenges facing blockchain technology today. As the blockchain landscape continues to evolve, BSC\u2019s strategic innovations and growing community are likely to drive further advancements and widespread adoption.

    "},{"location":"bnb-smart-chain/developers/faucet/","title":"Faucet - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/faucet/#claim-test-tbnb-tokens","title":"Claim test tBNB Tokens","text":""},{"location":"bnb-smart-chain/developers/faucet/#claim-tbnb-from-online-faucet","title":"Claim tBNB from Online Faucet","text":"

    To get some tBNB of BSC testnet for testing purposes, you can use the online faucet to claim your tokens.

    1. Copy your wallet address and paste the address into the textbox

    2. Select the tokens you need to claim. Major pegged tokens like BUSD, USDT, and others are supported.

    3. Please note if your wallet balance is larger than 1 tBNB, you can not get new tBNB from the Discord bot faucet.*

    "},{"location":"bnb-smart-chain/developers/faucet/#claim-tbnb-from-discord","title":"Claim tBNB from Discord","text":"
    1. Visit the BNB Chain Discord faucet channel
    2. Type /faucet {your receiver account} and sent.
    3. You will receive 0.3 tBNB in few seconds.

    You can only claim once in 24 hours.

    "},{"location":"bnb-smart-chain/developers/faucet/#claim-tbnb-from-third-party-faucets","title":"Claim tBNB from Third-party Faucets","text":"

    You can also claim tBNB from the following third-party faucets

    1. https://faucet.quicknode.com/binance-smart-chain/bnb-testnet

    2. https://faucet.chainstack.com/bnb-testnet-faucet

    3. https://thirdweb.com/opbnb-testnet

    "},{"location":"bnb-smart-chain/developers/quick-guide/","title":"Quick Guide - BNB Smart Chain (BSC)","text":"

    If you are a developer looking to build applications on the BNB Smart Chain (BSC), this document provides all the essential information you need.

    "},{"location":"bnb-smart-chain/developers/quick-guide/#getting-started","title":"Getting Started","text":"

    BNB Smart Chain (BSC) is a high-performance blockchain network.

    Since BSC is EVM-compatible, your existing Ethereum smart contract skills will seamlessly transfer to BSC.

    "},{"location":"bnb-smart-chain/developers/quick-guide/#connecting","title":"Connecting","text":"

    Here are some resources to help you get connected to the BSC network:

    "},{"location":"bnb-smart-chain/developers/quick-guide/#get-tokens","title":"Get Tokens","text":"

    BNB is the native utility token of BNB Smart Chain and is used to pay transaction fees. For the testnet, you can use the faucet to obtain test tokens on BSC.

    For the mainnet, you can withdraw tokens directly from a centralized exchange (CEX) which supports BSC network(e.g. Binance).

    "},{"location":"bnb-smart-chain/developers/quick-guide/#json-rpc-api","title":"JSON-RPC API","text":"

    Interacting with BSC requires sending requests to specific JSON-RPC API methods. BSC\u2019s APIs are compatible with Geth. - JSON-RPC API

    "},{"location":"bnb-smart-chain/developers/quick-guide/#developer-tools","title":"Developer Tools","text":"

    For more tools and details, you can refer to BSC Dev Tools.

    "},{"location":"bnb-smart-chain/developers/rpc/","title":"RPC - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/rpc/#json-rpc-endpoint","title":"JSON-RPC Endpoint","text":"

    JSON-RPC endpoints refers to the network location where a program could transfer its RPC requests to access server data. Once you connect a decentralized application to an RPC endpoint, you can access the functionalities of different operations, which could enable real-time usage of blockchain data. BNB Chain provides several RPC endpoints for connectinto both its Minent and Testnet. In this section, we list the JSON-RPC endpoints that can be used for connecting to BNB Smart Chain.

    "},{"location":"bnb-smart-chain/developers/rpc/#one-click-adding-bsc-network","title":"One-click adding BSC network","text":"

    Visit the ChainList and connect to your wallet, it will add alive RPC endpoints.

    "},{"location":"bnb-smart-chain/developers/rpc/#rpc-endpoints-for-bnb-smart-chain","title":"RPC Endpoints for BNB Smart Chain","text":"

    The rate limit of BSC endpoint on Testnet and Mainnet is 10K/5min.

    eth_getLogs is disabled on below Mainnet endpoints, please use 3rd party endpoints from here. If you need to pull logs frequently, we recommend using WebSockets to push new logs to you when they are available.

    "},{"location":"bnb-smart-chain/developers/rpc/#bsc-mainnet-chainid-0x38-56-in-decimal","title":"BSC Mainnet (ChainID 0x38, 56 in decimal)","text":"

    You could find more endpoints from here.

    "},{"location":"bnb-smart-chain/developers/rpc/#bsc-testnet-chainid-0x61-97-in-decimal","title":"BSC Testnet (ChainID 0x61, 97 in decimal)","text":""},{"location":"bnb-smart-chain/developers/rpc/#rpc-providers","title":"RPC Providers","text":""},{"location":"bnb-smart-chain/developers/rpc/#starting-http-json-rpc","title":"Starting HTTP JSON-RPC","text":"

    You can start the HTTP JSON-RPC with the \u2013http flag

    ## mainnet\ngeth attach https://bsc-dataseed.bnbchain.org\n\n## testnet\ngeth attach https://bsc-testnet-dataseed.bnbchain.org\n
    "},{"location":"bnb-smart-chain/developers/rpc/#json-rpc-methods","title":"JSON-RPC methods","text":"

    Please refer to this wiki page or use Postman: https://documenter.getpostman.com/view/4117254/ethereum-json-rpc/RVu7CT5J?version=latest

    "},{"location":"bnb-smart-chain/developers/wallet-configuration/","title":"Wallet Configuration - BNB Smart Chain (BSC)","text":""},{"location":"bnb-smart-chain/developers/wallet-configuration/#wallet-configuration","title":"Wallet configuration","text":"

    You can use any Ethereum wallet with BSC. For instance, I will show you how to set up Metamask and Trustwallet for BSC.

    Testnet

    Mainnet

    "},{"location":"bnb-smart-chain/developers/wallet-configuration/#references-how-to-configure-trustwallet-or-metamask","title":"References - How to configure Trustwallet or Metamask","text":"

    Trustwallet

    After you install the Trustwallet in your browser, you can go to settings->network.

    Select add custom network and enter the network information I mentioned above.

    Metamask

    After you install the metamask in your browser, you can go to settings -> networks -> add network page.

    Select add manual network and enter the network information.

    Depending on your location and preference, you can choose from a variety of RPC endpoints for BSC. For more information about the endpoints and their features, please refer to the network information document that we have prepared for you. To ensure the best performance and user experience, you can test the latency of each endpoint before you configure it with your wallet.

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/","title":"Archive Node - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#how-to-run-an-archive-node-on-bnb-smart-chain","title":"How to Run an Archive Node on BNB Smart Chain","text":""},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#what-is-an-archive-node","title":"What is an archive node?","text":"

    Simply speaking, an archive node is a full node running with an additional special option, --gcmode archive. It stores all the historical data of the blockchain starting from the genesis block. As compared to a typical full node that just holds all the state change data for some latest blocks, an archive node always stores them for each block.

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#why-is-an-archive-node-important","title":"Why is an archive node important?","text":"

    Developers are limited to querying the limited recent blocks to check the balance of an address and the state of a smart contract with a full node. It is hard to get all what they want as the blockchain is moving forward at the same time, while they can query any block at a specific point in time with an archive node. Archive nodes are used by various applications on the blockchain for challenging use cases, including but not limited to the followings:

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#suggested-requirements","title":"Suggested Requirements","text":"

    Running an archive node will take a high cost as it includes all the block and state change data. First of all it needs the disk with sufficient capacity; besides this, the CPU and disk performance should be good enough to catch up with the latest block height. You can refer to the suggested hardware requirements.

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#how-to-run-an-archive-node-for-bsc-mainnet","title":"How to run an archive node for BSC mainnet?","text":""},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#run-with-an-erigon-client","title":"Run with an Erigon client","text":"

    Erigon has supported BSC mainnet. You can also refer to Free public BNB Smart Chain Archive Snapshot for the guide to run a BSC archive node with an Erigon client. The owner has switched to using an Erigon client for a BSC archive node recently. You can download the archive snapshot which is a tarball from aws s3. The s3 path is \u201cs3://public-blockchain-snapshots/bsc/erigon-latest.tar.zstd\u201d. This path is public, but is configured as requester-pays. Also this means you\u2019ll need an AWS account in order to download it.

    aws s3 cp --request-payer=requester  \"s3://public-blockchain-snapshots/bsc/erigon-latest.tar.zstd\"   local_data_dir\n\ntar --use-compress-program=unzstd -xvf erigon-latest.tar.zstd\n
    ./erigon --chain=bsc --datadir  local_data_dir\n

    The known Issue with an Erigon client is that it does not really keep up with the latest blocks as mentioned in the Github. If you want to keep up with the latest blocks it is suggested to run a BSC archive node with high performance disk such as NVME, or run a BSC full node with a Geth client at the same time which means you need one proxy that will ask Erigon if it has the block height and if not forward it to the Geth client.

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#run-with-a-reth-client","title":"Run with a Reth client","text":"

    Reth now supports the BSC network and demonstrates superior performance compared to Geth and Erigon in recent benchmark tests. You can utilize reth to operate an archive node; for more information, refer to Reth Node.

    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/","title":"Boot Node - BSC Develop","text":"

    Through the maintenance release v1.2.12 4, Boot Nodes were introduced on the BSC mainnet. BSC Boot Nodes are similar to Ethereum Boot Nodes, refer here for more details. The main benefit of Boot Nodes is that it would be easier for user to connect to the BSC network. Users would no longer need to setup the StaticNodes in config.toml, just leave it empty and make sure delete the BootstrapNodes field in config.toml.

    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#impact-to-users","title":"Impact To Users","text":""},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#static-nodes-could-be-stopped","title":"Static Nodes Could Be Stopped","text":"

    Previously, BSC provides a list of StaticNodes for users to connect to the network, they are working as a full node and also serving the P2P discovery protocol. New BSC nodes connect to the BSC network through these StaticNodes. It works, but is not quite stable, since they could have very heavy workload.

    These static nodes could be stopped and replaced by Boot Nodes in the future. And the StaticNodes list provided before could no longer be available. Like the list provided in v1.2.11 5:

    StaticNodes = [\n\"enode://fe0bb07eae29e8cfaa5bb15b0db8c386a45b7da2c94e1dabd7ca58b6327eee0c27bdcea4f08db19ea07b9a1391e5496a28c675c6eee578154edae4fa44640c5d@54.228.2.74:30311\",\n\"enode://c307b4cddec0aea2188eafddedb0a076b9289402c63217b4c81eb7f34761c7cfaf6b075e93d7357169e226ff1bb4aa3bd71869b4c76cf261e2991005ddb4d4aa@3.81.81.182:30311\",\n\"enode://84a76ad1fab6164cbb00179dd07c96755141ffb75d5d387f45295e6ecfcc9e12a720f1f3dca8318449eeff768d13e9d49a414d2b522d1bcf2919aebf4852ab46@44.198.58.179:30311\",\n\"enode://41d57b0f00d83016e1bb4eccff0f3034aa49345301b7be96c6bb23a0a852b9b87b9ed11827c188ad409019fb0e578917d722f318665f198340b8a15ae8beff36@34.252.87.229:30311\",\n\"enode://accbc0a5af0af03e1ec3b5e80544bdceea48011a6928cd82d2c1a9c38b65fd48ec970ba17bd8c0b0ec21a28faec9efe1d1ce55134784b9207146e2f62d8932ba@54.162.32.1:30311\",\n\"enode://e333532e47a14dba7603c9ab0598e68be2c0822200855844edd45f50bfba481451ca5ee5247dbca2b54fe522e74a658edc15c8eed917360e1a289b3ab78ecf4c@3.250.36.7:30311\",\n\"enode://9f005be9111a6152884fd575abb55bddb1e7f726510c96cddde57a9bba84ffa4952a89d7632c9c9dd50d3750f83966a73a0f7ed793f253a3691b84a687b29b6c@3.88.177.211:30311\",\n\"enode://5451251a9902e658154456ea98ebdd93313e54496ce0a6ca2242fe4db882940d78d758c85a36485af54b0841270f2bdbff64d66c45976f3ed1dd912f7649c831@3.236.189.129:30311\",\n\"enode://a232f92d1e76447b93306ece2f6a55ac70ca4633fae0938d71a100757eaf8526e6bbf720aa70cba1e6d186be17291ad1ee851a35596ec6caa2fdf135ce4b6b68@107.20.124.16:30311\",\n\"enode://62c516645635f0389b4c851bfc4545720fac0607de74942e4ea7e923f4fa2ac0c438c146e2f0721c8ce06dca4e7f30f5c0136569d9f4b6a827c62b980fd53272@52.215.57.20:30311\",\n\"enode://c014bbf48209cdf8ca6d3bf3ff5cf2fade45104283dcfc079df6c64e0f4b65e4afe28040fa1731a0732bd9cbb90786cf78f0174b5de7bd5b303088e80d8e6a83@54.74.101.143:30311\",\n\"enode://710ed272e03b92c803cd165e5fa071da015815d312f17d107a43ad3b12b0f05c830c58ced2df7547294f5365fe76cdcf1a58f923ee5612d247a6d5b80cfe16a8@34.245.31.55:30311\",\n\"enode://768af449287561c0f17bb5dc5d98a1c6a4b1798cb41159bd0a7bfebdc179e39ad8076d7292caa9344eecb94a5f7499e632c29cc4edbdf2e8ada3f7c8c7b2a64b@3.95.173.72:30311\",\n\"enode://8428650e034341479d0ca3142bcd412f400ba47454bb7caeb88cfeb9bb60c21e45153eddf3e334d5d94ae67609ec2ac44816b346a2b3216d94a7c095883141e3@54.195.188.155:30311\"\n]\n
    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#to-join-the-network-with-bootnodes","title":"To Join The Network With BootNodes","text":"
    ...\n[Node.P2P]\nMaxPeers = 200\nNoDiscovery = false\nBootstrapNodes = [\n\"enode://433c8bfdf53a3e2268ccb1b829e47f629793291cbddf0c76ae626da802f90532251fc558e2e0d10d6725e759088439bf1cd4714716b03a259a35d4b2e4acfa7f@52.69.102.73:30311\",\n\"enode://571bee8fb902a625942f10a770ccf727ae2ba1bab2a2b64e121594a99c9437317f6166a395670a00b7d93647eacafe598b6bbcef15b40b6d1a10243865a3e80f@35.73.84.120:30311\",\n\"enode://fac42fb0ba082b7d1eebded216db42161163d42e4f52c9e47716946d64468a62da4ba0b1cac0df5e8bf1e5284861d757339751c33d51dfef318be5168803d0b5@18.203.152.54:30311\",\n\"enode://3063d1c9e1b824cfbb7c7b6abafa34faec6bb4e7e06941d218d760acdd7963b274278c5c3e63914bd6d1b58504c59ec5522c56f883baceb8538674b92da48a96@34.250.32.100:30311\",\n\"enode://ad78c64a4ade83692488aa42e4c94084516e555d3f340d9802c2bf106a3df8868bc46eae083d2de4018f40e8d9a9952c32a0943cd68855a9bc9fd07aac982a6d@34.204.214.24:30311\",\n\"enode://5db798deb67df75d073f8e2953dad283148133acb520625ea804c9c4ad09a35f13592a762d8f89056248f3889f6dcc33490c145774ea4ff2966982294909b37a@107.20.191.97:30311\"\n]\nStaticNodes = []\nListenAddr = \":30311\"\n...\n
    ...\n[Node.P2P]\nMaxPeers = 200\nNoDiscovery = false\nStaticNodes = []\nListenAddr = \":30311\"\n..\n
    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#to-run-a-boot-node","title":"To Run A Boot Node","text":"

    Boot nodes are super-lightweight nodes, they can be ran by a very cheap device, like: 2 cores, 2GB memory, 20GB disk. \\ If you want to support the BSC ecosystem by providing new boot nodes, you can follow this guide to do it.

    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#help","title":"Help","text":"

    Since boot nodes have been introduced recently, if you get any problem in using it, please let us know. You may just create new issue in BSC GitHub repo.

    "},{"location":"bnb-smart-chain/developers/node_operators/docker/","title":"Run BSC Nodes using Docker - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#how-to-run-a-fullnode-using-bsc-docker-image","title":"How to Run A Fullnode Using BSC Docker Image","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#resources","title":"Resources","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#supported-platforms","title":"Supported Platforms","text":"

    We support running a BSC docker image on Mac OS X, Linux, and Windows.

    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#steps-to-run-a-fullnode-in-docker","title":"Steps to Run a Fullnode in Docker","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#install-docker","title":"Install Docker","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#post-install","title":"Post install:","text":"

    Start docker during boot up:

    systemctl enable docker.service\nsystemctl enable containerd.service\n
    Add user \u201cubuntu\u201d to group docker so the user has privileges to run docker commands:
    usermod -aG docker ubuntu\n
    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#pull-bsc-node-image","title":"Pull BSC Node Image","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#download-bsc-node-config-files","title":"Download BSC Node Config Files","text":"

    Download genesis.json and config.toml by:

    Mainnet

    wget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep mainnet |cut -d\\\" -f4)\nunzip mainnet.zip\n
    Testnet
    wget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep testnet |cut -d\\\" -f4)\nunzip testnet.zip\n
    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#running-docker-container","title":"Running Docker Container","text":"
    1. Dockers Variables and Config file Location

    Important Environment Variables to note:

    $BSC_HOME = /bsc\n$DATA_DIR = /data\n
    File location:

    Essentially we need to bind mount two directories:

    Mount Local Docker Blockchain data data/node /bsc/node Config files config /bsc/config
    1. Download data on local host Download latest chaindata snapshot from here. Follow the guide to structure your files.

    2. Start container

    You can also use ETHEREUM OPTIONS to overwrite settings in the configuration file:

    docker run -v $(pwd)/config:/bsc/config -v $(pwd)/data/node:/bsc/node -p 8575:8575 --rm --name bsc -it ghcr.io/bnb-chain/bsc:1.1.18_hr --http.addr 0.0.0.0 --http.port 8575 --http.vhosts '*' --verbosity 5\n
    * -p 8575:8575: This will map port 8575 from host to container, so it exposes 8575 on host node. * \u2013http \u2013http.addr 0.0.0.0: Extra Geth flags to enable RPC and listen on all network interfaces of the container.

    NOTE: port 8575 is the default port for the RPC service on TESTNET. If you are using mainnet the default port is 8545.

    1. Start Geth console
      geth attach http://localhost:8575\n
    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#how-to-access-the-container","title":"How to access the container","text":"

    Execute bash (shell/terminal) on the container named bsc:

    docker exec -it bsc bash\n
    Once logged in you can perform regular tasks you would do on a node without docker."},{"location":"bnb-smart-chain/developers/node_operators/docker/#how-to-check-node-running-status","title":"How to Check Node Running Status","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#check-synchronization","title":"Check Synchronization","text":"

    Start Geth Console:

    geth attach ipc:node/geth.ipc\n
    Once started, run:
    >eth.syncing\n
    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#check-geth-logs","title":"Check Geth Logs","text":"
    tail -f node/bsc.log\n
    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/","title":"Fast Node - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#fast-node-on-bnb-smart-chain","title":"Fast Node on BNB Smart Chain","text":""},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#note","title":"Note","text":"

    Fast Node does not generate Trie Data when syncing. Once the Fast Node is running, there is no way to switch back to Full Node. Need to re-download snapshot data to restore it to Full Node.

    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#fast-node-functions","title":"Fast Node Functions","text":""},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#steps-to-run-a-fast-node","title":"Steps to Run a Fast Node","text":""},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#download-the-pre-build-binaries-from-release-page-or-follow-the-instructions-below","title":"Download the pre-build binaries from release page or follow the instructions below:","text":"
    # Linux\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_linux |cut -d\\\" -f4)\nmv geth_linux geth\nchmod -v u+x geth\n\n# MacOS\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_mac |cut -d\\\" -f4)\nmv geth_mac geth\nchmod -v u+x geth\n
    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#download-the-config-files","title":"Download the config files","text":"

    Download genesis.json and config.toml by:

    wget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep mainnet |cut -d\\\" -f4)\nunzip mainnet.zip\n
    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#download-snapshot","title":"Download snapshot","text":"

    Download latest chaindata snapshot from here. Follow the guide to structure your files.

    :::note Your \u2013datadir flag should point to the extracted chaindata folder path :::

    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#prune-all-trie-data","title":"Prune all trie data","text":"

    Fast node does not need trie data anymore, prune the trie data by the following command.

    ./geth snapshot insecure-prune-all --datadir ./node  ./genesis.json\n
    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#start-fast-node-without-snapshot-verification","title":"Start Fast Node Without Snapshot Verification","text":"

    You can start Fast Node without snapshot verification by verify nodes.

    ## start a fast node\n./geth --tries-verify-mode none --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n

    Or start Fast Node With Snapshot Verification 1. Add verifyNodes peers in config.toml.

    [Node.P2P]\nMaxPeers = 1350\nNoDiscovery = false\nBootstrapNodes = [\"enode://...\", \"enode://...\", ...]\nVerifyNodes = [\"enode://...\", \"enode://...\", ...]\nStaticNodes = [\"enode://...\", \"enode://...\", ...]\nListenAddr = \":30311\"\nEnableMsgEvents = false\n
    1. Start your fast node with snapshot verification by verify nodes.
    ## start a fast node\n./geth --tries-verify-mode full --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n
    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/","title":"Full Node - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/full_node/#how-to-run-a-fullnode-on-bnb-smart-chain","title":"How to Run A Fullnode on BNB Smart Chain","text":""},{"location":"bnb-smart-chain/developers/node_operators/full_node/#fullnodes-functions","title":"Fullnodes Functions","text":""},{"location":"bnb-smart-chain/developers/node_operators/full_node/#supported-platforms","title":"Supported Platforms","text":"

    We support running a full node on Mac OS X, Linux, and Windows.

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#steps-to-run-a-fullnode","title":"Steps to Run a Fullnode","text":""},{"location":"bnb-smart-chain/developers/node_operators/full_node/#sync-from-snapshot-recommended","title":"Sync From Snapshot (Recommended)","text":"
    1. Download the pre-build binaries from the release page or follow the instructions below

      # Linux\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_linux |cut -d\\\" -f4)\nmv geth_linux geth\nchmod -v u+x geth\n\n# MacOS\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_mac |cut -d\\\" -f4)\nmv geth_mac geth\nchmod -v u+x geth\n
    2. Download the config files

      Download genesis.json and config.toml by:

      # mainnet\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep mainnet |cut -d\\\" -f4)\nunzip mainnet.zip\n\n# testnet\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep testnet |cut -d\\\" -f4)\nunzip testnet.zip\n
    3. Download snapshot Download latest chaindata snapshot from here. Follow the guide to structure your files.

      Tip

      Your \u2013datadir flag should point to the folder where the extracted snapshot data is. In our case, we created a new folder named node, and we moved the extracted snapshot data to this folder.

      mv server/data-seed/geth/chaindata node/geth/chaindata\nmv server/data-seed/geth/chaindata node/geth/triecache\n
    4. Start a full node

      ./geth --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n

      Note

      Make sure you use the version of geth you downloaded with wget above, and not your local installation of geth, which might be the wrong version. For all geth nodes, DO NOT use -pipecommit flag

      Tip

      It is recommended to run a fast node, which is a full node with the flag --tries-verify-mode none set if you want high performance and care little about state consistency. Check here for full details on running a fast node. It will run with Hash-Base Storage Scheme by default

      ./geth --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0 --tries-verify-mode none\n

      It will run with Path-Base Storage Scheme. It will enable inline state prune, keeping the latest 90000 blocks\u2019 history state by default.

      ./geth --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0 --tries-verify-mode none --state.scheme path\n
    5. Monitor node status

      You can monitor the log from ./node/bsc.log by default. When your node has started syncing, you should be able to see the following output:

      t=2022-09-08T13:00:27+0000 lvl=info msg=\"Imported new chain segment\"             blocks=1    txs=177   mgas=17.317   elapsed=31.131ms    mgasps=556.259  number=21,153,429 hash=0x42e6b54ba7106387f0650defc62c9ace3160b427702dab7bd1c5abb83a32d8db dirty=\"0.00 B\"\nt=2022-09-08T13:00:29+0000 lvl=info msg=\"Imported new chain segment\"             blocks=1    txs=251   mgas=39.638   elapsed=68.827ms    mgasps=575.900  number=21,153,430 hash=0xa3397b273b31b013e43487689782f20c03f47525b4cd4107c1715af45a88796e dirty=\"0.00 B\"\nt=2022-09-08T13:00:33+0000 lvl=info msg=\"Imported new chain segment\"             blocks=1    txs=197   mgas=19.364   elapsed=34.663ms    mgasps=558.632  number=21,153,431 hash=0x0c7872b698f28cb5c36a8a3e1e315b1d31bda6109b15467a9735a12380e2ad14 dirty=\"0.00 B\"\n
    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#sync-from-genesis-block-not-recommended","title":"Sync From Genesis Block (Not Recommended)","text":"

    Caution

    It is recommended to use HBSS with level DB for archive node, PBSS for archive node is not supported yet.

    Note

    To sync from genesis block, you would need a more powerful hardware. Server should at least have 40k IOPS and be at least an i3/i3en series server.

    ## start a full node\n./geth --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n
    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#sync-mode","title":"Sync Mode","text":"

    There are two sync modes for running a full node: snap and full which can be specified by flag \u2013syncmode.

    The snap sync mode is used for initial sync, which will download the latest states rather than execute the blocks from the genesis. When the initial sync is done, it will switch to full sync automatically.

    The full sync mode can also be used to do initial sync, which will execute all the blocks since genesis. But it is not recommended, since the amount of historical data is too large. Instead, you can download a snapshot from the official repo and start full sync from the snapshot.

    If the flag \u2013syncmode is not provided, the default sync mode will depend on the state of the data folder. It will be snap mode if you sync from genesis or full mode if you start from a snapshot.

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#full-sync-with-greenfield-peer-optional","title":"Full Sync with Greenfield Peer (Optional)","text":"

    Opting for full sync mode means your node will only need block headers and bodies from other network peers. To expedite this process, consider utilizing the Greenfield Peer.

    This data seed, offered by Greenfield, allows for a more efficient synchronization. Configure your BSC node to connect with the Greenfield Light Peer by modifying your configuration file settings. For comprehensive instructions, see Light Peer.

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#local-private-network","title":"Local Private Network","text":"

    Please refer to BSC-Deploy Tools to setup a local private network.

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#node-maintenance","title":"Node Maintenance","text":"

    Please read this guide

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#upgrade-geth","title":"Upgrade Geth","text":"

    Please read this guide

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/","title":"Best Practices - BNB Smart Chain Node Configuration - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#bnb-smart-chain-bsc-node-configuration-best-practices","title":"BNB Smart Chain (BSC) Node Configuration: Best Practices","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#hardware-specifications","title":"Hardware Specifications","text":"

    To ensure optimal performance and reliability, it is crucial to select the appropriate node type based on your specific requirements for transaction processing and state querying on the BNB Smart Chain.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#fast-node-recommended-configuration","title":"Fast Node (Recommended Configuration)","text":"

    For users requiring access to the latest world state in a lightweight mode, the fast node is the ideal choice. It demands less from your system\u2019s CPU and disk space.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#archive-node","title":"Archive Node","text":"

    For comprehensive access to the entire historical world state of the BSC mainnet, consider deploying an Archive Node. Detailed instructions are available at BSC Erigon GitHub repository.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#full-node","title":"Full Node","text":"

    To obtain the latest world state and verify the validity of the state or to generate data proofs, a standard Full Node is suitable.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#peers-configuration","title":"Peers Configuration","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#mainnet","title":"Mainnet","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#testnet","title":"Testnet","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#clarification-of-the-snapshots","title":"Clarification of the snapshots","text":"

    As BSC will mainly support PBSS & PebbleDB, we will only cover snapshots of PBSS&PebbleDB and ignore snapshot of HashBased&LevelDB here. Please refer to this reference.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#troubleshooting-for-no-peers-in-testnet","title":"Troubleshooting for no peers in testnet","text":"

    Reference over here

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#monitoring-metrics-and-alerts","title":"Monitoring Metrics and Alerts","text":"

    To maintain node health and performance, monitor the following key metrics:

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#performance-optimization","title":"Performance Optimization","text":"

    BSC nodes offer configurable cache settings to enhance performance. It is advisable to allocate approximately one-third of the physical memory to the cache. For example, with 64GB of physical memory, the cache setting can be configured as:

    --cache 20000\n
    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#keep-track-of-syncing-speed","title":"Keep Track of Syncing Speed","text":"
    t=2021-05-13T17:17:17+0800 lvl=info msg=\"Imported new chain segment\"             blocks=11  txs=3701  mgas=482.461  elapsed=8.075s    mgasps=59.744  number=7,355,800 hash=0x84e085b1cd5b1ad4f9a954e2f660704c8375a80f04326395536eedf83363942f age=12h38m32s dirty=\"583.73 MiB\"\nt=2021-05-13T17:17:20+0800 lvl=info msg=\"Deep froze chain segment\"               blocks=117 elapsed=263.497ms number=7,265,806 hash=0x7602f6b960b4092d39ff49781c64404a047e2c78bc166f071ee8714020c39b2e\nt=2021-05-13T17:17:25+0800 lvl=info msg=\"Imported new chain segment\"             blocks=17  txs=5025  mgas=740.885  elapsed=8.125s    mgasps=91.177  number=7,355,817 hash=0xde7a2a76ff7b38414acf3b360bb427d2d0b7dd1f8fe2afe2ffd59d64b237a81b age=12h37m49s dirty=\"594.65 MiB\"\nt=2021-05-13T17:17:33+0800 lvl=info msg=\"Imported new chain segment\"             blocks=18  txs=5108  mgas=748.016  elapsed=8.354s    mgasps=89.535  number=7,355,835 hash=0x757c476f9fe30fc6ef001fb4a03fa991843cf3ed271f21cfc01a9bba5e5eff98 age=12h37m3s  dirty=\"604.39 MiB\"\nt=2021-05-13T17:17:42+0800 lvl=info msg=\"Imported new chain segment\"             blocks=18  txs=5612  mgas=799.778  elapsed=8.260s    mgasps=96.815  number=7,355,853 hash=0x73e87742ef4405ffefec987fc4b8b19e69c54b8f914c27ea69a502fae4d735e0 age=12h36m18s dirty=\"613.03 MiB\"\n

    Your syncing speed is mgasps. The value should be around 100. If you are syncing slowly, please check the speed of your disk.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#use-chaindata-snapshot","title":"Use Chaindata Snapshot","text":"

    Please download the chain data snapshot and extract to your home folder to speed up

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#store-your-bnb-with-a-hardware-wallet","title":"Store Your BNB with a Hardware Wallet","text":"

    The most valuable assets of a validator are two keys: one for signing transactions and another for signing blocks

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#securing-your-full-node-rpc-from-hackers","title":"Securing Your Full Node RPC from Hackers","text":"

    Please do not expose your RPC endpoints to public network.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#account-private-keys","title":"Account Private keys","text":"

    To protect your BNB, do not share your 24 words with anyone. The only person who should ever need to know them is you. In short, HSMs are affordable, performant and portable pieces of hardware that help to securely generate, store and manage your private keys. Malware attacks and remote extraction of private keys are much more difficult when an HSM is configured properly.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#software-vulnerabilities","title":"Software Vulnerabilities","text":"

    To protect your BNB, you should only download software directly from official sources, and make sure that you\u2019re always using the latest, most secure version

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#running-server-as-a-daemon","title":"Running Server as a Daemon","text":"

    It is important to keep geth running at all times. There are several ways to achieve this, and the simplest solution we recommend is to register geth as a systemd service so that it will automatically get started upon system reboots and other events.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#set-up-a-backup-node","title":"Set up a Backup Node","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#steps-to-run-a-backup-node","title":"Steps to Run a Backup Node","text":"
    1. Install the latest version of geth
    2. Sync to the latest height using fast sync mode. You can either download the latest snapshot or start fast sync once your node is fully synced
    3. Shut down your node gracefully kill -HUP $(pgrep geth)
    4. Restart your node.
    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#why-node-will-be-offline-for-a-while-after-restart-or-what-will-happen-if-the-client-is-force-killed","title":"Why Node will be Offline for a While After Restart? or What will Happen If the Client is Force Killed?","text":"

    After running (synchronized) for a long period of time and being abruptly terminated, only archived nodes are expected to quickly re-synchronize upon restart.

    Steps to reproduce:

    Reasons

    If Geth crashes (or is not shut down gracefully), the recent state held in memory is lost and needs to be regenerated. It takes Geth a long time to restore the states.

    The root reason is that geth does flush the state trie periodically. The period is defined as trieTimeout in config.toml.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#how-to-upgrade-a-backup-node-to-become-a-validator-node","title":"How to Upgrade a Backup Node to Become a Validator Node?","text":"

    You can stop mining new blocks by sending commands in geth console

    Connect to your validator node with geth attach ipc:path/to/geth.ipc

    miner.stop()\n

    Then, let backup node resume validating ,

    miner.start()\n
    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#securing-the-validators","title":"Securing the Validators","text":"

    Each validator candidate is encouraged to run its operations independently, as diverse setups increase the resilience of the network. Due to the high amount invested by validators it is highly essential to protect them against different DoS and DDoS attacks. In this section, we disscuss the security mechanism adopted by BSC for its validators.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#sentry-nodes-ddos-protection","title":"Sentry Nodes (DDOS Protection)","text":"

    Validators are responsible for ensuring that the network can sustain denial of service attacks. One recommended way to mitigate these risks is for validators to carefully structure their network topology in a so-called sentry node architecture. Sentry nodes can be quickly spun up or change their IP addresses. Because the links to the sentry nodes are in private IP space, an internet based attacked cannot disturb them directly. This will ensure validator block proposals and votes always make it to the rest of the network.

    To setup your sentry node architecture you can follow the instructions below:

    1. Build a private network and setup trusted private connections between the validator node and its sentry

    Please do not expose your validator fullnode RPC endpoints to the public network.

    Install your fullnode

    1. Set sentry as peers for the validator node

    In the console of the sentry node, run admin.nodeInfo.enode You should get something similar to this.

    enode://f2da64f49c30a0038bba3391f40805d531510c473ec2bcc7c201631ba003c6f16fa09e03308e48f87d21c0fed1e4e0bc53428047f6dcf34da344d3f5bb69373b@[::]:30306?discport=0\n

    !!! Note: [::] will be parsed as localhost (127.0.0.1). If your nodes are on a local network check each individual host machine and find your IP with ifconfig If your peers are not on the local network, you need to know your external IP address (use a service) to construct the enode URL. Copy this value and in the console of the first node run,

    Update config.toml file of validator node

    # make node invisible\nNoDiscovery = true\n# connect only to sentry\nStaticNodes = [\"enode://f2da64f49c30a0038bba3391f40805d531510c473ec2bcc7c201631ba003c6f16fa09e03308e48f87d21c0fed1e4e0bc53428047f6dcf34da344d3f5bb69373b@[10.1.1.1]:30306\"]\n
    This will return true if successful, but that doesn\u2019t mean the node was added successfully.

    To confirm run admin.peers and you should see the details of the node you just added.

    That way your validator node will try to peer with your provided sentry nodes only.

    1. Confirm the connection

    To confirm run admin.peers and you should see the details of the node you just added.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#firewall-configuration","title":"Firewall Configuration","text":"

    geth uses several TCP ports for different purposes.

    geth use a listener (TCP) port and a discovery (UDP) port, both on 30303 by default.

    If you need to run JSON-RPC, you\u2019ll also need TCP port 8545. Note that JSON-RPC port should not be opened to the outside world, because from there you can do admin operations.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/","title":"Node Maintenance - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#node-maintenance","title":"Node Maintenance","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#binary","title":"Binary","text":"

    All the clients are suggested to upgrade to the latest release. The latest version is supposed to be more stable and has better performance.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#storage","title":"Storage","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#prune-state","title":"Prune State","text":"

    According to the test, the performance of a full node will degrade when the storage size reaches a high volume(previously it was 1.5TB, which is an experimental value, the latest number needs to be updated). We suggest that the fullnode always keep light storage by pruning the storage.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#how-to-prune","title":"How to Prune","text":"
    1. Stop the BSC node.
    2. Run nohup geth snapshot prune-state --datadir {the data dir of your bsc node} &. It will take 3-5 hours to finish.
    3. Start the node once it is done.

    The maintainers should always have a few backup nodes in case one of the nodes is getting pruned. The hardware is also important, make sure the SSD meets: 3 TB of free disk space, solid-state drive(SSD), gp3, 8k IOPS, 500 MB/S throughput, read latency <1ms (if node is started with snap sync, it will need NVMe SSD).

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#prune-ancient-data-in-real-time","title":"Prune Ancient Data in Real Time","text":"

    Ancient data is block data that is already considered immutable. This is determined by a threshold which is currently set at 90000. This means that blocks older than 90000 are considered ancient data. We recommend the --prunceancient flag to users who don\u2019t care about the ancient data. This is also advised for users who want to save disk space since this will only keep data for the latest 90000 blocks. Note that once this flag is turned on, the ancient data will not be recovered again and you cannot go back running your node without this flag in the start-up command.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#how-to-use-the-flag","title":"How to use the flag","text":"
    ./geth --tries-verify-mode none --config /server/config.toml --datadir /server/node --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0 --pruneancient=true --syncmode=full\n
    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#prune-block-tools","title":"Prune Block Tools","text":"

    A new offline feature introduced in v1.1.8 to prune undesired ancient block data. It will discard block, receipt, and header in the ancient database to save space.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#how-to-prune_1","title":"How to prune","text":"
    1. Stop the BSC Node.
    2. Run

      ./geth snapshot prune-block --datadir /server/node --datadir.ancient ./chaindata/ancient --block-amount-reserved 1024\n

      block-amount-reserved is the number of ancient data blocks that you want to keep after pruning.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#light-storage","title":"Light Storage","text":"

    When the node crashes or been force killed, the node will sync from a block that was a few minutes or a few hours ago. This is because the state in memory is not persisted into the database in real time, and the node needs to replay blocks from the last checkpoint once it start. The replaying time depends on the configuration TrieTimeout in the config.toml. We suggest you raise it if you can tolerate with long replaying time, so the node can keep light storage.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#upgrade-geth","title":"Upgrade Geth","text":"

    Please read this guide

    "},{"location":"bnb-smart-chain/developers/node_operators/reth_node/","title":"Reth Node - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/reth_node/#reth-node-for-bsc","title":"Reth Node for BSC","text":"

    BSC Reth is a cutting-edge Rust client developed in collaboration with Paradigm, designed to provide seamless support for BNB Smart Chain (BSC). It aims to enhance client diversity on the BNB Chain by offering a secure and efficient execution client.

    "},{"location":"bnb-smart-chain/developers/node_operators/reth_node/#hardware-specifications","title":"Hardware Specifications","text":"

    To run BSC Reth effectively, ensure your system meets the following hardware requirements:

    "},{"location":"bnb-smart-chain/developers/node_operators/reth_node/#running-bsc-reth","title":"Running BSC Reth","text":"
    1. Download source code and build binary.

      git clone https://github.com/bnb-chain/reth.git\ncd reth\nmake build-bsc\n
    2. Start the reth node, it will run in archive mode by default. You can add the --full flag to start a full node.

      # for mainnet\nexport network=bsc\n\n# for testnet\n# export network=bsc-testnet\n\n./target/release/bsc-reth node \\\n    --datadir=./datadir \\\n    --chain=${network} \\\n    --http \\\n    --http.api=\"eth, net, txpool, web3, rpc\" \\\n    --log.file.directory ./datadir/logs\n
    3. Optionally, you can run the reth node with docker.

      # for mainnet\nexport network=bsc\n\n# for testnet\n# export network=bsc-testnet\n\n# check this for version of the docker image, https://github.com/bnb-chain/reth/pkgs/container/bsc-reth\nexport version=latest\n\n# the directory where reth data will be stored\nexport data_dir=/xxx/xxx\n\ndocker run -d -p 8545:8545 -p 30303:30303 -p 30303:30303/udp -v ${data_dir}:/data \\\n    --name bsc-reth ghcr.io/bnb-chain/bsc-reth:${version} node \\\n    --datadir=/data \\\n    --chain=${network} \\\n    --http \\\n    --http.api=\"eth, net, txpool, web3, rpc\" \\\n    --log.file.directory /data/logs\n
    "},{"location":"bnb-smart-chain/developers/node_operators/reth_node/#snapshot","title":"Snapshot","text":"

    To synchronize a BSC reth node from scratch to the current block height can be a time-consuming process. As We benchmark Reth(v1.0.0) on AWS lm4gn.8xlarge(32 core 128G) with 2 x 7500 NVMe SSD for BSC mainnet. It may take approximately 30 days to sync the latest block on BSC mainnet for an archive node and 24 days for a full node.

    Given the extended duration required for stage synchronization of the BSC network, the BNB Chain team is developing a segmented snapshot download solution, scheduled for release in the near future. Currently, developers seeking to expedite the process can obtain archive node snapshots from community-maintained repositories. These snapshots offer a faster alternative to syncing from genesis, allowing for quicker node setup and network participation.

    "},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/","title":"Upgrade Geth - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/#how-to-upgrade-geth","title":"How to Upgrade Geth","text":"

    Updating geth is as easy as it gets. You just need to download and install the newer version of geth, shutdown your node and restart with the new software. Geth will automatically use the data of your old node and sync the latest blocks that were mined since you shut down the old software.

    "},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/#step-1-compile-the-new-version-or-download-new-pre-build-binaries-from-release","title":"Step 1: Compile the New Version or download new pre-build binaries from release","text":"
    git clone https://github.com/bnb-chain/bsc\n# Enter the folder bsc was cloned into\ncd bsc\n# Compile and install bsc\nmake geth\n
    # Download pre-build binaries\n\n# Linux\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_linux |cut -d\\\" -f4)\nmv geth_linux geth\nchmod -v u+x geth\n\n# MacOS\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_mac |cut -d\\\" -f4)\nmv geth_mac geth\nchmod -v u+x geth\nmake geth\n
    "},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/#step-2-stop-geth","title":"Step 2: Stop Geth","text":"
    $ pid=`ps -ef | grep geth | grep -v grep | awk '{print $2}'`\n$ kill  $pid\n
    "},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/#step-3-restart","title":"Step 3: Restart","text":"

    Note

    Make sure to use the same start-up command you used before the upgrade. So in this case we use the same command as in our tutorial

    ./geth --config ./config.toml --datadir ./node --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n
    "},{"location":"bnb-smart-chain/developers/paymaster/overview/","title":"Overview - BSC Paymaster","text":""},{"location":"bnb-smart-chain/developers/paymaster/overview/#eoa-based-paymaster","title":"EOA Based Paymaster","text":"

    This document introduces a paymaster solution specifically designed for Externally Owned Account (EOA) wallets, differing from the paymaster defined in EIP-4337. With minimal modifications, wallets can integrate this solution to support gas fee sponsorship, significantly enhancing user experience.

    "},{"location":"bnb-smart-chain/developers/paymaster/overview/#what-is-eoa-based-paymaster","title":"What is EOA based Paymaster","text":"

    The paymaster in EIP-4337 (Account Abstraction via Entry Point Contract Specification) is a crucial component designed to enhance the flexibility and user experience of Ethereum transactions. It allows a third party to pay for a user\u2019s transaction fees, removing the need for users to hold ETH to pay for gas.

    While EIP-4337 introduced the revolutionary concept of paymasters for smart contract wallets, a significant portion of the Ethereum ecosystem still relies on EOAs. Recognizing this, this present a groundbreaking paymaster solution specifically designed for EOA wallets. This innovation brings the benefits of transaction sponsorship and enhanced user experience to the broader BNB Chain user base, without requiring a shift to smart contract wallets. The EOA paymaster solution aims to democratize access to sponsored transactions, making blockchain interactions more user-friendly and cost-effective for millions of existing EOA wallet users.

    "},{"location":"bnb-smart-chain/developers/paymaster/overview/#how-does-it-work","title":"How does it Work","text":"

    Under BEP322\u2019s Proposer-Builder Separation (PBS) architecture, a significant shift occurs in transaction processing:

    1. Validator Role: Validators no longer verify individual transaction gas prices within a block.
    2. Transaction Bundling: Private transactions are grouped into bundles and submitted to builders.
    3. Prioritization: Builders prioritize based on the aggregate gas price of each bundle.
    4. Intra-Bundle Flexibility: Within a single bundle, gas prices can vary, allowing for zero-fee and higher-fee transactions to coexist.

    This flexibility enables innovative features such as sponsored gas fees and gasless transactions.

    "},{"location":"bnb-smart-chain/developers/paymaster/overview/#definitions","title":"Definitions","text":"

    Bundle: An ordered array of transactions that execute atomically, ensuring all transactions in the bundle are processed together or not at all.

    Builder: A new stakeholder in the MEV supply chain responsible for constructing blocks. Builders package transaction bundles, individual transactions from the public txpool, and private transaction order flow into proposed blocks.

    Proposer: A validator who selects the most profitable block from multiple builders\u2019 proposals for inclusion in the blockchain.

    Paymaster: An infrastructure component that enables transaction sponsorship, allowing self or third parties to cover gas fees.

    Sponsor Policy: A set of rules defined by the gas sponsor to determine which transactions qualify for sponsorship. This may include criteria such as whitelisted transaction senders or specific transaction types.

    "},{"location":"bnb-smart-chain/developers/paymaster/overview/#overall-workflow","title":"Overall Workflow","text":"

    The gas sponsorship process involves several key components and steps:

    1. User Initiation:

    2. Paymaster Submission:

    3. Sponsor Policy Verification:

    4. Sponsorship Processing:

    5. Bundle Creation and Submission:

    6. Builder Selection and Block Proposal:

    7. Blockchain Inclusion:

    8. Post-Transaction Processing:

    This solution leverages the BEP322 Proposer-Builder Separation architecture to enable seamless gas sponsorship without requiring significant changes to existing wallet infrastructures. It provides a flexible system that can accommodate various sponsorship models while maintaining the security and integrity of the blockchain network.

    "},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/","title":"Paymaster-API - BSC Paymaster","text":""},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#paymaster-api-spec","title":"Paymaster API Spec","text":"

    To facilitate widespread adoption and ensure interoperability across diverse wallet implementations, it is crucial to establish a standardized set of interface specifications for paymasters. This standardization will enable wallet developers to integrate gas sponsorship features efficiently and consistently, regardless of the specific paymaster service they choose to utilize.

    "},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#api-spec","title":"API Spec","text":"

    Paymaster needs to implement a JSON-RPC API called\u00a0pm_isSponsorable, so that it can return sponsor and policy information to wallets. Paymaster also needs to implement\u00a0eth_sendRawTransaction\u00a0JSON-RPC API. The detailed API Specs are defined as below:

    "},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#pm_issponsorable","title":"pm_isSponsorable","text":"

    Request Parameters

    Example:

    {\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"method\": \"pm_isSponsorable\",\n  \"params\": [\n    {\n      \"to\": \"0x...\", // an address\n      \"from\": \"0x...\", // an address\"value\": \"0xa1\",\n      \"data\": \"0x\",\n      \"value\": \"0x1b4\",\n      \"gas\" : \"0x101b4\"\n    }\n  ]\n}\n

    Response Fields

    Example:

    {\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"result\": {\n    \"Sponsorable\": true,\n    \"SponsorPolicy\": \"a sample policy name\"\n  }\n}\n
    "},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#_1","title":"Paymaster-API - BSC Paymaster","text":""},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#eth_sendrawtransaction","title":"eth_sendrawtransaction","text":"

    The\u00a0eth_sendrawtransaction\u00a0API implemented by the Paymaster should follow this\u00a0Ethereum API Spec. The client can create a new message call transaction or a contract creation for signed transactions via\u00a0eth_sendrawtransaction\u00a0API.

    Request Parameters

    The\u00a0params\u00a0should contain the signed transaction data.

    Example:

    {\n   \"jsonrpc\": \"2.0\",\n   \"id\": 1,\n   \"method\": \"eth_sendRawTransaction\",\n   \"params\": [\n \"0x02f86a6102850df8475800850df84758000a94cd9c02358c223a3e788c0b9d94b98d434c7aa0f18080c080a0bcb0e8ffa344e4b855c6e13ee9e4e5d22cff6ad8bd1145a93b93c5d332100c2ca03765236eba5fbb357e35014fd19ba4b3c6b87f3793bd14dddf7913fc8dcc88bf\"\n   ]\n}\n

    Response Fields

    DATA, 32 Bytes - the transaction hash.

    Example:

    {\n  \"id\":1,\n  \"jsonrpc\": \"2.0\",\n  \"result\": \"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331\"\n}\n
    "},{"location":"bnb-smart-chain/developers/paymaster/wallet-integration/","title":"Paymaster Wallet Integration - BSC Paymaster","text":""},{"location":"bnb-smart-chain/developers/paymaster/wallet-integration/#wallet-integration","title":"Wallet Integration","text":"

    This guide outlines the steps for wallet developers to integrate paymaster services, enabling gas fee sponsorship for their users. By following these standards, wallets can offer seamless, gasless transactions across multiple paymaster providers.

    "},{"location":"bnb-smart-chain/developers/paymaster/wallet-integration/#interaction-workflow","title":"Interaction Workflow","text":"

    Integration involves modifying the transaction creation and sending process to interact with paymaster services. For detailed information about the paymaster API interface, please refer to this document.

    The main steps are:

    1. Transaction Preparation:
    2. User Notification:
    3. Transaction Signing:
    4. Submission to Paymaster:
    5. Response Handling:
    6. Transaction Monitoring:
    "},{"location":"bnb-smart-chain/developers/paymaster/wallet-integration/#best-practice","title":"Best Practice","text":"
    1. Always check sponsorability before modifying gas price.
    2. Provide clear user feedback about sponsorship status.
    3. Implement proper error handling for cases where sponsorship fails.
    4. Consider fallback mechanisms for non-sponsored transactions.
    "},{"location":"bnb-smart-chain/governance/apis/","title":"Governance APIs - BSC Governance","text":""},{"location":"bnb-smart-chain/governance/apis/#bsc-governance-apis","title":"BSC Governance APIs","text":"

    This guide gives an overview of governance operations for BSC, such as creating proposals, casting votes, and executing them.

    "},{"location":"bnb-smart-chain/governance/apis/#governance-contracts","title":"Governance Contracts","text":"

    The BSC governance facilitates decentralized decision-making within the BSC ecosystem, utilizing two primary smart contracts: GovToken for governance token management and Governor for proposal management and voting.

    "},{"location":"bnb-smart-chain/governance/apis/#create-proposal","title":"Create Proposal","text":"

    To create a proposal, you need to call the propose function of Governor with the following parameters:

    function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory\n    description) public returns (uint256 proposalId)\n
    "},{"location":"bnb-smart-chain/governance/apis/#cast-vote","title":"Cast Vote","text":"

    To cast a vote, you need to call the castVote function of Governor with the following parameters:

    function castVote(uint256 proposalId, uint8 support, string memory reason) public returns (uint256)\n
    "},{"location":"bnb-smart-chain/governance/apis/#check-proposal-state","title":"Check Proposal State","text":"

    To get the state of a proposal, you need to call the state function of Governor with the following parameters:

    function state(uint256 proposalId) public view returns (ProposalState)\n
    "},{"location":"bnb-smart-chain/governance/apis/#queue-proposal","title":"Queue Proposal","text":"

    To schedules the proposal for execution, you need to call the queue function of Governor with the following parameters:

    function queue(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)\npublic returns (uint256 proposalId)\n
    "},{"location":"bnb-smart-chain/governance/apis/#execute-proposal","title":"Execute Proposal","text":"

    To apply the changes after the timelock delay, you need to call the execute function of Governor with the following parameters:

    function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)\npublic payable returns (uint256)\n
    "},{"location":"bnb-smart-chain/governance/apis/#delegate-vote","title":"Delegate Vote","text":"

    To delegate voting power to someoneles, you need to call the delegateVote function of GovToken with the following parameters:

    function delegateVote(address delegator, address delegatee) external\n
    "},{"location":"bnb-smart-chain/governance/apis/#contract-abi","title":"Contract ABI","text":"

    For the full interfaces of Governor, please refer to the ABI file.

    For the full interfaces of GovToken, please refer to the ABI file.

    "},{"location":"bnb-smart-chain/governance/overview/","title":"Overview - BSC Governance","text":""},{"location":"bnb-smart-chain/governance/overview/#bsc-governance-overview","title":"BSC Governance Overview","text":"

    BEP-297 introduces the native governance module for BSC, drawing inspiration from the OpenZeppelin Governor. Here are the key features of BSC Governance:

    "},{"location":"bnb-smart-chain/governance/overview/#workflow-overview","title":"Workflow Overview","text":""},{"location":"bnb-smart-chain/governance/overview/#submit-proposal","title":"Submit Proposal","text":""},{"location":"bnb-smart-chain/governance/overview/#cast-vote","title":"Cast Vote","text":""},{"location":"bnb-smart-chain/governance/overview/#execute-proposal","title":"Execute Proposal","text":""},{"location":"bnb-smart-chain/governance/overview/#delegation-of-voting-power","title":"Delegation of Voting Power","text":"

    Staking credit holders can delegate their voting power to participate in governance if they lack time or expertise. Delegating to a trusted party like a validator or a professional service allows them to benefit from expertise and avoid losing rewards by not voting.

    "},{"location":"bnb-smart-chain/governance/temp-check/","title":"Temperature Check - BSC Governance","text":""},{"location":"bnb-smart-chain/governance/temp-check/#bsc-governance-temperature-check","title":"BSC Governance Temperature Check","text":""},{"location":"bnb-smart-chain/governance/temp-check/#overview","title":"Overview","text":"

    BNB Chain governance involves a two-step process: temperature check and final decision voting. The temperature check, typically conducted through the Snapshot platform, allows any BNB holder to gauge community sentiment on a proposal. If the proposal receives enough support, it proceeds to the final decision voting phase. This phase often involves on-chain voting by validators or those with staked BNB, and the outcome determines whether the proposal is implemented or rejected.

    "},{"location":"bnb-smart-chain/governance/temp-check/#submit-a-proposal","title":"Submit a Proposal","text":"

    Info

    Anyone who staked more than 1BNB can create proposals.

    Step 1: Head to the space which you wish to create your proposal for.

    Connect with the wallet provider - make sure the connected wallet is where you delegate BNB

    Step 2: Click New proposal in space sidebar

    Fill in the following fields: - Title - Description - Discussion link

    Step 3: Select the desired voting system, specify the possible vote options, and define the duration of your proposal. Make sure you allow enough time for users to vote.

    Step 4: Click Publish - and you can see your proposal in the proposals list on the space page.

    "},{"location":"bnb-smart-chain/governance/temp-check/#voting","title":"Voting","text":""},{"location":"bnb-smart-chain/governance/temp-check/#vote-on-a-proposal","title":"Vote on a Proposal","text":"

    Info

    All BNBChain delegators can vote for proposals.

    Step 1: Log in to voting space URL: https://snapshot.org/#/bnbchain-dao.eth

    Step 2: Go to the snapshot link of the proposal. For example, in this case, a community member created a voting proposal for BEP-341.

    https://snapshot.org/#/bnbchain-dao.eth/proposal/0xd2ad975fbe1abd4bf71a5032239650741a64af0133feec83f43b98bc42fa7efe

    Step 3: Connect your wallet and vote

    After you connect your wallet, make sure to use the same address of your BNB Staking. And choose the voting option.

    "},{"location":"bnb-smart-chain/governance/temp-check/#delegate-voting-power","title":"Delegate Voting Power","text":"

    Step 1: Go to https://snapshot.org/#/delegate/bnbchain-dao.eth

    Step 2: Enter the address you want to delegate to.

    Step 3: Click Confirm to save your delegation.

    "},{"location":"bnb-smart-chain/governance/temp-check/#undelegate-voting-power","title":"Undelegate Voting Power","text":"

    Step 1: Go to https://snapshot.org/#/delegate/bnbchain-dao.eth

    Step 2: Find the current delegatees in Top delegates.

    Step 3: Click the \u2018x\u2019 button along a delegatee to undelegate, the wallet will ask user to sign and send transaction to bsc

    "},{"location":"bnb-smart-chain/governance/user-guide/","title":"User Guide - BSC Governance","text":""},{"location":"bnb-smart-chain/governance/user-guide/#manage-governance-with-tally-dapp","title":"Manage Governance with Tally dApp","text":"

    This document provides a guide on how to participate in governance on the BNB Smart Chain (BSC) using Tally. It covers the process of delegating voting power, creating proposals, voting on proposals, and executing proposals.

    BNB Chain DAOs are created on Tally both for the mainnet and testnet.

    "},{"location":"bnb-smart-chain/governance/user-guide/#parameters","title":"Parameters","text":"

    There are several parameters which will affect the governance process on the BSC.

    Parameter Description Mainnet Value Testnet Value votingDelay a fixed duration after which users can vote to a proposal 0 hour 0 hour votingPeriod the voting period before tally 7 days 1 day proposalThreshold a fixed amount of gov BNB needed for a proposal 200 govBNB 100 govBNB quorumNumberRator the percentage of the total voting power required to produce a final vote result 10% 10% startGovThreshold the total supply of gov token to enable the gov function 10M BNB 10M BNB minPeriodAfterTheQuorum the time to add for voting when a proposal reaches quorum 1 day 1 hour timerlockDelay the timer locker duration to execute a proposal 1 day 6 hours"},{"location":"bnb-smart-chain/governance/user-guide/#governance-process-guide","title":"Governance Process Guide","text":"

    You need to connect to your Web3 wallet (e.g., TrustWallet, BEW, Metamask) for the following operations.

    "},{"location":"bnb-smart-chain/governance/user-guide/#delegate-voting-power","title":"Delegate Voting Power","text":"

    After you have delegated your BNB to a BSC validator, you can start participating in the BSC governance. To participate in BSC governance, you first need to delegate your voting power to a validator or yourself if you wish to vote directly.

    You can click the My voting power button in the top right corner of the screen to delegate your voting power.

    You can delegate your voting power to yourself if you want to vote/create proposals directly, or to others if you want him/her to vote/create proposals on your behalf.

    If you delegate the voting power to yourself, you will see the current number of your voting power to participate in the governance.

    "},{"location":"bnb-smart-chain/governance/user-guide/#create-proposals","title":"Create Proposals","text":"

    If you have sufficient voting power (i.e., greater than the proposalThreshold), you can create proposals on the BSC network. Be noted that a user can only has one proposal in active/pending state at a time to prevent spamming.

    To create a proposal, click on the \u201cCreate new proposal\u201d button on the top right corner of the screen.

    After you have created a proposal, you can add a title, description, and a list of actions for the proposal.

    A text proposal only requires a title and a description, and it will not be executed by the network for there is no action.

    To add an action, click on the \u201cAdd action\u201d button, and fill in the details of the action.

    After you input all the details, click on the \u201cPublish\u201d will publish your proposal.

    You can also cancel a proposal by clicking on the \u201cCancel proposal\u201d button.

    "},{"location":"bnb-smart-chain/governance/user-guide/#vote-on-proposals","title":"Vote on Proposals","text":"

    Once a proposal is live (i.e., after the votingDelay and before the votingPeriod), you can cast your vote to support or oppose the proposal. To vote on a proposal, click on the \u201cVote on chain\u201d button.

    You can cast For, or Against, or Abstain votes to the proposal.

    "},{"location":"bnb-smart-chain/governance/user-guide/#execute-proposals","title":"Execute Proposals","text":"

    If a proposal reaches the quorum (i.e., reaches the quorumNumberRator of the total voting power) and it passes (i.e., more than 50% of the voted voting power supports the proposal), it can be executed by the network.

    To execute a proposal, firstly the proposal needs to be queued by clicking the Queue button.

    After the proposal is queued and exceeds the timelock duration (i.e, the timerlockDelay duration), it can be executed by anyone by clicking the Execute button.

    "},{"location":"bnb-smart-chain/governance/user-guide/#more-references","title":"More References","text":""},{"location":"bnb-smart-chain/slashing/monitor/","title":"Monitor - BSC Slashing","text":""},{"location":"bnb-smart-chain/slashing/monitor/#bsc-slash-monitor","title":"BSC Slash Monitor","text":""},{"location":"bnb-smart-chain/slashing/monitor/#monitor-slash","title":"Monitor Slash","text":"

    Generally, without maliciously altering BSC node code or mistakenly running the validator, validators would not typically incur double sign slashes or malicious vote slashes.

    Validators should consistently monitor for potential slashes due to node unavailability, as it can lead to slash events.

    As best practice, it is advisable to keep monitoring the event log of the slash contract on the BSC scanner at https://bscscan.com/address/0x0000000000000000000000000000000000001001#events.

    You can check your validator\u2019s slash indicator in the above contract. Pay attention to values above 30. If it goes over 50, the validator will be slashed. If it goes over 150, the validator will be jailed.

    "},{"location":"bnb-smart-chain/slashing/monitor/#unjail-validator","title":"Unjail Validator","text":"

    Once a Validator is slashed into a jailed state, the Validator must wait for a specific period before being able to unjail. Once the waiting period elapses, the Validator can access the BNB Staking dApp and proceed to click on the unjail button to initiate the unjail transaction.

    BNB Staking dApp:

    "},{"location":"bnb-smart-chain/slashing/overview/","title":"Overview - BSC Slashing","text":""},{"location":"bnb-smart-chain/slashing/overview/#bsc-slashing-overview","title":"BSC Slashing Overview","text":"

    Slashing is a component of on-chain governance that penalizes malicious or negative actions. Anyone can submit a slash transaction on BSC, which involves providing evidence and paying fees. Successful submissions yield significant rewards. Currently, there are three types of slashable cases.

    "},{"location":"bnb-smart-chain/slashing/overview/#double-sign","title":"Double Sign","text":"

    It is quite a serious error and very likely a deliberate offense when a validator signs more than one block with the same height and parent block. The reference protocol implementation should already have logic to prevent this, so only the malicious code can trigger this. When Double Sign happens, the validator should be removed from the Validator Set right away.

    Anyone can submit a slash transaction with the evidence of Double Sign to the BSC Slash Contract, which should contain the 2 block headers with the same height and parent block, sealed by the offending validator. Upon receiving the evidence, the contract will verify its validity.

    The validator will be removed from validator set, a predefined amount of BNB would be slashed from the self-delegated BNB of the validator. Both validator and its delegators will not receive the staking rewards. Part of the slashed BNB will be allocated to the submitter\u2019s address, which is a reward and larger than the cost of submitting slash request transaction. The rest of the slashed BNB will be allocated to the other validators\u2019 credit addresses, and distributed to all delegators in the same way as blocking reward.

    "},{"location":"bnb-smart-chain/slashing/overview/#malicious-fast-finality-vote","title":"Malicious Fast Finality Vote","text":"

    It is quite a serious error and very likely a deliberate offense when a validator signs two fast finality votes with the same target height or the span of one vote including the span of another vote. The reference protocol implementation should already have logic to prevent this, so only the malicious code can trigger this. When Malicious Vote happens, the validator should be removed from the Validator Set right away.

    Anyone can submit slash transaction with the evidence of Malicious Vote to the BSC Slash Contract. Evidence of malicious voting needs to be provided, which includes two conflicting votes and the voting key used for the signature. Upon receiving the evidence, the contract will verify its validity.

    The validator will be removed from the current set of validators, and the submitter will receive the reward from the system contract. A predefined amount of BNB would be slashed from the self-delegated BNB of the validator. Both validator and its delegators will not receive the staking rewards. The slashed BNB will be allocated to the other validators\u2019 credit addresses, and distributed to all delegators in the same way as blocking reward.

    "},{"location":"bnb-smart-chain/slashing/overview/#unavailability","title":"Unavailability","text":"

    The liveness of BSC relies on everyone in the Proof of Staked Authority validator set can produce blocks timely when it is their turn. Validators can miss their turn due to any reason, especially problems in their hardware, software, configuration or network. This instability of the operation will hurt the performance and introduce more indeterministic into the system.

    There is an internal smart contract that records the missed blocking metrics of each validator. If the metrics exceed the set threshold, the blocking reward for the validator will not be given to them but shared with other validators performing better. This process aims to gradually remove poorly-operating validators from the set, reducing rewards for their delegators.

    If the metrics stay above a higher threshold, the validator will be removed from rotation, and a set amount of BNB will be deducted from their self-delegated BNB. This action results in both validators and delegators not receiving their staking rewards.

    "},{"location":"bnb-smart-chain/slashing/slash-rules/","title":"BSC Slash Rules - BSC Slashing","text":""},{"location":"bnb-smart-chain/slashing/slash-rules/#bsc-slash-rules","title":"BSC Slash Rules","text":"

    Three types of malicious behaviors can lead to slashing on the BSC network.

    "},{"location":"bnb-smart-chain/slashing/slash-rules/#double-sign","title":"Double Sign","text":"

    Anyone can submit a slash request with evidence of Double Sign. The evidence must adhere to the following rules:

    If the evidence is valid:

    1. 200BNB would be slashed from the self-delegated BNB of the validator
    2. The remaining slashed BNB will be allocated to the credit addresses of validators participating in the next distribution
    3. Set the validator jailed with a duration of 30 days, and remove it from the active validator set
    "},{"location":"bnb-smart-chain/slashing/slash-rules/#malicious-vote","title":"Malicious Vote","text":"

    Anyone can submit a slash request on BSC with the evidence of Malicious Vote. The evidence must adhere to the following rules:

    If the evidence is valid:

    1. 200BNB would be slashed from the self-delegated BNB of the validator
    2. 5BNB would allocate to the submitter from the system reward contract as a reward if the validator is active when the evidence submitted
    3. The remaining slashed BNB will be allocated to the credit addresses of validators participating in the next distribution
    4. Set the validator jailed with a duration of 30 days, and remove it from the active validator set
    "},{"location":"bnb-smart-chain/slashing/slash-rules/#unavailability","title":"Unavailability","text":"

    There is an internal smart contract that records the missed blocking metrics of each validator.

    If a validator misses over 50 blocks in 24 hours, they will not receive the block reward; instead, it will be shared among other validators.

    If a validator misses more than 150 blocks in 24 hours:

    1. 10BNB would be slashed from the self-delegated BNB of the validator
    2. The slashed BNB will be allocated to the credit addresses of validators participating in the next distribution
    3. Set the validator jailed with a duration of 2 days, and remove it from the active validator set
    "},{"location":"bnb-smart-chain/staking/developer-guide/","title":"Build BSC Staking dApps Guide - BSC Staking","text":""},{"location":"bnb-smart-chain/staking/developer-guide/#build-bsc-staking-dapps-guide","title":"Build BSC Staking dApps Guide","text":"

    This guide covers essential staking operations like creating validators, editing their information, and delegating. Developers can use these interfaces to build stake-related dApps.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#stakehub-contract","title":"StakeHub Contract","text":"

    The BSC staking mainly uses the smart contracts StakeHub for validator and delegation management.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#creating-validator","title":"Creating Validator","text":"

    To create a validator, use the createValidator function with the following parameters:

      function createValidator(\n    address consensusAddress,\n    bytes calldata voteAddress,\n    bytes calldata blsProof,\n    Commission calldata commission,\n    Description calldata description\n) external payable\n

    Note: Creating a validator requires locking 1 BNB, and the transaction must be sent with a sufficient BNB amount to cover this lock amount plus any self-delegation, in total 2001BNB.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#edit-validator","title":"Edit Validator","text":""},{"location":"bnb-smart-chain/staking/developer-guide/#edit-consensus-address","title":"Edit Consensus Address","text":"

    To change the consensus address of a validator, use the editConsensusAddress function with the following parameters:

    function editConsensusAddress(address newConsensusAddress) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#edit-commission-rate","title":"Edit Commission Rate","text":"

    To update the commission rate of a validator, use the editCommissionRate function with the following parameters:

    function editCommissionRate(uint64 newCommissionRate) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#edit-description","title":"Edit Description","text":"

    To update the description of a validator, use the editDescription function with the following parameters:

    function editDescription(Description memory newDescription) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#edit-vote-address","title":"Edit Vote Address","text":"

    To change the vote address of a validator, use the editVoteAddress function with the following parameters:

    function editVoteAddress(bytes calldata newVoteAddress, bytes calldata blsProof) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#delegation-operations","title":"Delegation Operations","text":""},{"location":"bnb-smart-chain/staking/developer-guide/#delegate","title":"Delegate","text":"

    To delegate BNB to a validator, call the delegate function with the following parameters:

    function delegate(address operatorAddress, bool delegateVotePower) external payable\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#undelegate","title":"Undelegate","text":"

    To undelegate BNB from a validator, use the undelegate function with the following parameters:

    function undelegate(address operatorAddress, uint256 shares) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#redelegate","title":"Redelegate","text":"

    To redelegate BNB from one validator to another, use the redelegate function with the following parameters:

    function redelegate(address srcValidator, address dstValidator, uint256 shares, bool delegateVotePower) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#claim","title":"Claim","text":"

    To claim undelegated BNB after the unbonding period, use the claim function for a single request or claimBatch for multiple requests:

    function claim(address operatorAddress, uint256 requestNumber) external\n
    function claimBatch(address[] calldata operatorAddresses, uint256[] calldata requestNumbers) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#precision-loss","title":"Precision Loss","text":"

    During the conversion process between credit tokens and BNB, it is inevitably encounter the usage of integer division, which may results in a precision loss. It can lead to tangible issues. For example, a user who delegates 1 BNB and then decides to undelegate immediately. Due to the aforementioned precision loss, they will only be able to claim back 0.99..99 BNB, which is essentially 1 minus a tiny fraction (1e-18) of BNB.

    In staking pools like Lido and Rocket Pool, users might encounter similar issues. However, these issues can be effectively addressed through thoughtful product design. For instance, when displaying information to users, rounding up to only preserve eight decimal places could be one solution. Or instead of undelegating, users can exchange their credit tokens for BNB, with the exact conversion results prominently displayed.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#faqs","title":"FAQs","text":""},{"location":"bnb-smart-chain/staking/developer-guide/#what-is-validators-credit-contract","title":"What is validator\u2019s credit contract?","text":"

    For each validator, there is a credit contract which will be automatically deployed when it is created. Meanwhile, the contract cannot be upgraded or changed by any validator operator.

    The credit contract is a BEP20 contract, and the ABI is the same as Stake Credit contract.

    It provides functions for querying delegations, including:

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-the-sharesbnb-for-a-delegator","title":"How to get the shares/BNB for a delegator?","text":"

    For any specific validator, please call the balanceOf function of the validator\u2019s creat contract to get the delegator\u2019s shares. To get the BNB amount instead of shares, the function getPooledBNB can be used.

    To get the shares of all validators, please call the balanceOf function for each validator and sum up the results. Please refer to the following to see how to get the information of all validators, and use a muticall contract to improve the efficiency.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-calculate-the-bnb-amount-for-a-specific-amount-of-shares","title":"How to calculate the BNB amount for a specific amount of shares?","text":"

    The credit contract provides the getPooledBNBByShares function to calculate the BNB amount for some specific amount of shares.

    To do the vice visa, please use the getSharesByPooledBNB function to calculate the shares for some specific BNB amount.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-calculate-the-aprapy-of-a-validator","title":"How to calculate the APR/APY of a validator?","text":"

    Please be noted that each validator will have its own APR/APY, and the staking system will auto compound the rewards.

    The reward is distributed to each validator\u2019s BNB pool at 00:00:00 UTC time every day. To calculate the APR/APY of a validator, the total pooled BNB amount and the propagandising reward amount for the same day are needed.

    The StakeHub contract provides the getValidatorTotalPooledBNBRecord(address,uint256)(uint256) and getValidatorRewardRecord(address,uint256)(uint256) for the purpose.

    The following code shows how to calculate the APY at a given day:

    // example code, do not use it in production\n\n// stakehub is the instance of StakeHub contract\nstakeHub, _ := contracts.NewStakeHub(ethcommon.HexToAddress(\"0x0000000000000000000000000000000000002002\"), client.GetEthClient())\n\n// get how many blocks are in a day\ninterval, _ := stakeHub.BREATHEBLOCKINTERVAL(nil)\n\n// get the block time of a given block\nheader, _ := p.client.GetBlockHeader(blockHeight)\n\n// calculate the index paramter to call the following functions\nindex := int64(header.Time) / interval.Int64()\n\n// get the total pooled BNB amount and the crrospanding reward amount for the given validator and index\ntotalPooledBNB, _ := stakeHub.GetValidatorTotalPooledBNBRecord(nil, validatorOperatorAddress, index)\nreward, _ := stakeHub.GetValidatorRewardRecord(nil, validatorOperatorAddress, index)\n\n// calculate the APY\nrate, _ := big.NewFloat(0).Quo(big.NewFloat(0).SetInt(reward), big.NewFloat(0).SetInt(totalPooledBNB)).Float64()\napy := math.Pow(1+rate, 365) - 1.0\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-the-unbonding-delegations-of-a-delegator-and-the-unbonded-requests-which-can-be-claimed","title":"How to get the unbonding delegations of a delegator, and the unbonded requests which can be claimed?","text":"

    The credit contract provides the pendingUnbondRequest function to get the unbonding delegation count for a delegator. To review the details of an unbond request, please call the unbondRequest function with a index parameter to define which unbond request will be returned.

    To get the claimable unbonded requests, please call the claimableUnbondRequest function to get the count of claimable ones.

    To get the locked BNBs for unbonding requests, please use the lockedBNBs function. It has the parameter number to define the sum of first number unbonding requests\u2019 BNB locked in the delegator\u2019s unbond queue. Set the number to 0 to get all the locked BNBs.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-the-reward-of-a-delegator","title":"How to get the reward of a delegator?","text":"

    The contracts do not save the initial delegation amount of a delegator. To get the accumulated reward, the following steps can be taken: 1) track the initial delegation amount in your system, 2) call the getPooledBNB of the credit contract of a validator, 3) do the math.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-the-total-staking-address-of-a-validator","title":"How to get the total staking address of a validator?","text":"

    The contract does not provide a function to get the total staking address of a validator. It needs an offchain service to index Delegated, Redelegated, Undelegated events for the purpose.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-all-validators-information","title":"How to get all validators\u2019 information?","text":"

    The StakeHub contract provides the getValidators function to get all validators\u2019 information, including the operator addresses and credit contract addresses.

    To get more information of a specific validator, please refer to the following functions:

    "},{"location":"bnb-smart-chain/staking/overview/","title":"Overview - BSC Staking","text":""},{"location":"bnb-smart-chain/staking/overview/#bsc-staking-overview","title":"BSC Staking Overview","text":"

    BNB Smart Chain (BSC) operates on a Proof-of-Staked-Authority (PoSA) blockchain, with the staking mechanism proposed in BEP-294. This enables BNB holders to stake their tokens with specified validators to secure the network and earn staking rewards. Here\u2019s an overview covering the core staking concepts and operations on BSC.

    "},{"location":"bnb-smart-chain/staking/overview/#basic-concepts","title":"Basic Concepts","text":""},{"location":"bnb-smart-chain/staking/overview/#consensus-engine","title":"Consensus Engine","text":"

    BSC uses a consensus mechanism which combines DPoS and PoA for consensus, in this system:

    The staking mechanism is essential for determining the eligibility of validators to produce blocks.

    "},{"location":"bnb-smart-chain/staking/overview/#validator-set","title":"Validator Set","text":"

    The validator set is the group of nodes that are responsible for validating transactions and producing blocks on the BSC. The validator set is determined by the amount of staking each validator has, which reflects the amount of BNB staked by the validator and its delegators. The top validators with the most staking are selected as the active validator set, and they take turns to propose and vote on blocks. The rest of the validators are in the standby validator set, and they can join the active validator set if their staking increases or if some active validators drop out.

    Any organization or individual can become part of the validator set by creating their validator on-chain and securing sufficient delegations. Similarly, they can opt-out by simply withdrawing all their BNB delegations.

    Validators can also be removed from the validator set by slashing, which is a penalty for misbehaving or being offline.

    "},{"location":"bnb-smart-chain/staking/overview/#validator-election","title":"Validator Election","text":"

    There are different roles for validators:

    The validator set roles are determined every 24 hours based on the latest staking information.

    After UTC 00:00, the consensus engine sorts validators and updates the BSC validator set with the ranking information.

    "},{"location":"bnb-smart-chain/staking/overview/#system-contracts","title":"System Contracts","text":"

    There are several built-in contracts (i.e., system contracts) to facilitate the BSC staking.

    "},{"location":"bnb-smart-chain/staking/overview/#credit-contract","title":"Credit Contract","text":"

    Each validator has its own validator contract that manages staking credit and facilitates the exchange between credit and BNB. The token name of a staking credit is \u201cstake {{validator moniker}} credit\u201d, and the symbol is \u201cst{{validator moniker}}\u201d. The contract will be created by the Stake Hub Contract when a validator is created.

    Whenever a user delegates BNB, an equivalent quantity of credit tokens are created. On the other hand, when a user withdraws their delegation, a corresponding amount of credit tokens are destroyed, thereby releasing the BNB.

    "},{"location":"bnb-smart-chain/staking/overview/#reward-distribution","title":"Reward Distribution","text":"

    The staking reward comes from transaction fee - when a block is produced, the majority of the block fee will be collected as reward for the validator who proposed the block.

    Every day, a portion of the rewards collected will be directly sent to the operator account of the validator as commission, while the remaining portion will be sent to the corresponding validator credit contract. And when a user undelegates and claims his/her stakes, the accumulated reward and the original stake will be sent back to him/her.

    "},{"location":"bnb-smart-chain/staking/overview/#validator-operations","title":"Validator Operations","text":"

    Validators are nodes running BNB Smart Chain software, participating in the consensus process. They require a minimum BNB stake at their validator address and can receive delegations from other BNB holders. Validators earn rewards from transaction fees and share most of these rewards with their delegators.

    "},{"location":"bnb-smart-chain/staking/overview/#create-validator","title":"Create Validator","text":"

    To ensure the security of the network, becoming a validator on the BSC requires a minimum self-delegation of 2000 BNB. BNB holders can initiate a CreateValidator transaction with the StakeHub contract to become a validator. For more information, refer to Create BSC Validator.

    "},{"location":"bnb-smart-chain/staking/overview/#edit-validator","title":"Edit Validator","text":"

    Validators can update their information using transactions like EditConsensusAddress, EditCommissionRate, EditDescription, and EditVoteAddress.

    "},{"location":"bnb-smart-chain/staking/overview/#delegator-operations","title":"Delegator Operations","text":"

    Delegators are BNB holders who stake their BNB with a validator, sharing rewards. They can select any active or standby validator, switch between them, undelegate their BNB, and claim rewards anytime. Users can refer to the user guide for instructions on these actions.

    "},{"location":"bnb-smart-chain/staking/user-guide/","title":"User Guide - BSC Staking","text":""},{"location":"bnb-smart-chain/staking/user-guide/#manage-stakes-with-bnb-staking-dapp","title":"Manage Stakes with BNB Staking dApp","text":"

    Leverage the BNB staking dApp for streamlined management of your stakes. This guide provides a step-by-step walkthrough for using the dApp on both BSC testnet and mainnet.

    "},{"location":"bnb-smart-chain/staking/user-guide/#connect-wallet","title":"Connect Wallet","text":"

    To interact with the dApp, first connect your web3 wallet. Currently, TrustWallet (mainnet only) and MetaMask are supported, along with any wallets compatible with WalletConnect.

    "},{"location":"bnb-smart-chain/staking/user-guide/#delegate-stakes","title":"Delegate Stakes","text":"
    1. Select a validator to delegate your stakes to. Detailed information about each validator is available on their respective pages.
    2. Click the Delegate button to initiate a new delegation.

    3. Enter the amount of BNB you wish to delegate.

    4. After confirming the delegation, your connected wallet will prompt you to sign the transaction. Successful transactions will be visible in the My Staking page, complete with transaction hash.

    "},{"location":"bnb-smart-chain/staking/user-guide/#redelegate-stakes","title":"Redelegate Stakes","text":"

    On the My Staking page, you can manage your existing delegations.

    Note: A redelegation fee of 0.002% applies to discourage frequent switching between validators.

    1. Click Redelegate to shift your stake to a different validator.

    2. In the ensuing popup, select your new validator and specify the amount to redelegate. You can opt to move the entire amount or just a portion.

    "},{"location":"bnb-smart-chain/staking/user-guide/#undelegate-stakes","title":"Undelegate Stakes","text":"

    To claim your stakes and rewards, you need to undelegate.

    1. Click the Undelegate button next to the relevant delegation.

    2. You can choose to undelegate the entire amount or a portion. Note that undelegated stakes are subject to a 7-day unbonding period before they are returned to your account.

    "},{"location":"bnb-smart-chain/staking/user-guide/#claim-stakes","title":"Claim Stakes","text":"

    After the unbonding period, you can claim your stakes by clicking the Claim button.

    "},{"location":"bnb-smart-chain/validator/create-val/","title":"Create BSC Validator - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/create-val/#create-bsc-validator","title":"Create BSC Validator","text":"

    This guide outlines the process for creating a new validator on the BNB Smart Chain (BSC). The BNB staking dApp is the official tool for creating and managing validators on the BSC.

    "},{"location":"bnb-smart-chain/validator/create-val/#terminology","title":"Terminology","text":""},{"location":"bnb-smart-chain/validator/create-val/#steps","title":"Steps","text":""},{"location":"bnb-smart-chain/validator/create-val/#1-connecting-to-the-dapp","title":"1. Connecting to the dApp","text":"

    Please connect to the staking dApp using your Operator Address. Trust Wallet, MetaMask, and WalletConnect options are available for the step. Make sure that the account has more than 2001 BNB before moving on to the next step.

    "},{"location":"bnb-smart-chain/validator/create-val/#2-filling-out-the-form","title":"2. Filling out the form","text":"

    Navigate to the dApp and select the Become a Validator button in the right middle of the page to initiate the creation process.

    The following information is required to create a validator.

    "},{"location":"bnb-smart-chain/validator/create-val/#21-basic-information","title":"2.1 Basic Information","text":"

    You\u2019ll need to provide the following details on the Create Validator page:

    To enhance your validator\u2019s visibility, consider uploading additional information to the BSC validator directory. Your avatar, once uploaded, will be displayed in the staking dApp.

    "},{"location":"bnb-smart-chain/validator/create-val/#22-addresses","title":"2.2 Addresses","text":"

    The following addresses are required:

    "},{"location":"bnb-smart-chain/validator/create-val/#generate-consensus-address","title":"Generate Consensus Address","text":"

    Download the BSC geth binary from the official release page.

    Note: Make sure you are downloading the correct binary based on your machine\u2019s platform, e.g., if you are using MacOS, you should download the geth_mac file. In the following, we will refer the binary as geth for simplicity.

    To create a new account for mining, please use the following command and set a password for the account.

    geth account new --datadir ${DATA_DIR}\n

    This command will provide the public address (consensus address) and the path to your private key. Remember to back up the key file safely! A sample consensus address is 0x4b3FFeDb3470D441448BF18310cAd868Cf0F44B5.

    If you already have an account for mining, you can use the seed phrase to recover the account.

    geth account import --datadir ${DATA_DIR}\n
    "},{"location":"bnb-smart-chain/validator/create-val/#generate-bls-vote-address-and-proof","title":"Generate BLS Vote Address and Proof","text":"

    To create a new bls account please use the following command.

     geth bls account new --datadir ${DATA_DIR}\n

    If you already have a voting key, create a bls wallet and use the keyfile to recover it, using the following command.

     geth bls account import ${KEY_FILE} --datadir ${DATA_DIR}\n

    Then you can get your vote address by running the following command.

    geth bls account list --datadir ${DATA_DIR}\n

    A sample bls address is b5fe571aa1b39e33c2735a184885f737a59ba689177f297cba67da94bea5c23dc71fd4deefe2c0d2d21851eb11081f69.

    Then you can get your bls proof by running the following command.

    geth bls account generate-proof --chain-id ${BSC_CHAIN_ID} ${OPEATOR_ADDRESS} ${VOTE_ADDRESS}\n

    A sample bls proof is 0xaf762123d031984f5a7ae5d46b98208ca31293919570f51ae2f0a03069c5e8d6d47b775faba94d88dbbe591c51c537d718a743b9069e63b698ba1ae15d9f6bf7018684b0a860a46c812716117a59c364e841596c3f0a484ae40a1178130b76a5.

    "},{"location":"bnb-smart-chain/validator/create-val/#create-identity","title":"Create Identity","text":"

    Identity is used to associate the new validator with the old validator created on the BNB Beacon Chain. It should be left empty after the Beacon Chain fusion.

    "},{"location":"bnb-smart-chain/validator/create-val/#23-commissions","title":"2.3 Commissions","text":""},{"location":"bnb-smart-chain/validator/create-val/#24-self-delegation","title":"2.4 Self-delegation","text":""},{"location":"bnb-smart-chain/validator/create-val/#3-submitting-the-form","title":"3. Submitting the form","text":"

    Once you have filled out all the required information, click the Submit button to submit the transaction.

    "},{"location":"bnb-smart-chain/validator/manage-keys/","title":"Key Management for BSC Validator - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/manage-keys/#key-management-for-bsc-validator","title":"Key Management for BSC Validator","text":"

    BEP-294 and BEP-297 introduce the native staking and governance features for BNB Smart Chain (BSC). For a validator, when participating in staking (e.g., creating a validator, self-delegating) and governance, there are several wallet keys that will be involved. To help validators manage their keys and funds effectively and safely, the following practices are recommended.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#operator-key","title":"Operator Key","text":"

    The operator key is used for operating a validator, including creating a validator, editing the information of a validator, and undelegating. When creating a validator, the operator key is also used for self-delegating with more than 2001 BNB. When interacting with the new BSC staking dApp, the operator key is mostly involved.

    Be noted that the operator address can not be changed for a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet. There should be more than 2001 BNB in the operator account when creating a new validator.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#staking-key","title":"Staking Key","text":"

    For a validator, it can also use another key, different from the operator key, to manage his/her delegation if needed. Then, such a staking key will be used to delegate/undelegate/redelegate to different validators and claim rewards. This key could be used frequently, depending on how a validator manages its delegations and rewards.

    Be noted that this key is optional, depending on the needs of a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#consensus-key","title":"Consensus Key","text":"

    The consensus key is used for signing proposed blocks when mining blocks. No fund is needed for this account.

    Recommendation: Use a hot wallet so that it can be easily accessed by a validator node.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#fast-finality-vote-key","title":"Fast Finality Vote Key","text":"

    The fast finality vote key (BLS vote key) is used in the fast finality feature for signing votes of recently mined blocks. No fund is needed for this account.

    Recommendation: Use a hot wallet so that it can be easily accessed by a validator node.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#governance-vote-key","title":"Governance Vote Key","text":"

    The BEP-297 introduces the native BSC staking feature. A delegator (including validators for self-delegation) can delegate someone else to participate in governance on his/her behalf. When there is governance delegation, the governance vote key will be used for casting votes to BSC proposals. The related wallet should store some BNB for gas fees of the voting transaction.

    Be noted that this key is optional, depending on the needs of a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet.

    "},{"location":"bnb-smart-chain/validator/overview/","title":"BSC Validator Overview - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/overview/#bsc-validator-overview","title":"BSC Validator Overview","text":"

    BNB Smart Chain(BSC) relies on a system of multiple validators with Proof of Staked Authority (PoSA) consensus that can support short block time and lower fees. The most bonded validators in staking will have the opportunity to produce blocks. The double-sign detection and other slashing logics ensure security, stability, and chain finality.

    BSC conducts a daily election process post 00:00 UTC to select the top 45 active validators based on their staking rankings for block production. Among these, the 21 validators with the highest staked amounts are referred to as Cabinets, while the remaining 24 validators are known as Candidates. The remaining inactive validators must wait for the next round of elections to become active validators before they can participate in block production.

    In the set of 45 active validators, each epoch selects 18 validators from the Cabinets and 3 validators from the Candidates, forming a group of 21 validators as the consensus validators set for the current epoch to produce blocks. If a validator is elected as the consensus validator but fails to participate in produce blocks, it will face slashing consequences.

    Cabinets are more likely to be elected as consensus validators for block generation than Candidates, who have a slightly lower probability of being chosen for the same role. However, whether it\u2019s Cabinets or Candidates, if they are not online when it\u2019s their turn to produce a block, they will be slashed. This measure aims to encourage more validators to participate in the consensus, enhancing the decentralization and security of BSC.

    "},{"location":"bnb-smart-chain/validator/overview/#what-is-validator","title":"What is Validator?","text":"

    Validators on the BSC are nodes responsible for producing blocks and securing the network through the POSA consensus mechanism. They participate in packaging transactions, creating and validating blocks to secure the BSC network, earning BNB tokens as rewards in exchange.

    "},{"location":"bnb-smart-chain/validator/overview/#the-network-topology","title":"The Network Topology","text":"

    Validators on the BSC network are interconnected through a peer-to-peer (P2P) network, allowing for both direct and indirect connections. As a validator node operator, you have two operational modes to choose from:

    "},{"location":"bnb-smart-chain/validator/overview/#economics","title":"Economics","text":"

    Validator\u2019s rewards come from transaction fees and commission fees from delegators.

    Let us also assume that the reward for a block is 100 BNB and that a certain validator has 20% of self-bonded BNB and sets its commission rate to 20%. These tokens do not go directly to the proposer. Instead, they are shared among validators and delegators. These 100 BNB will be distributed according to each participant\u2019s stake:

    Commission: 80*20%= 16 BNB\nValidator gets: 100\\*20% + Commission = 36 BNB\nAll delegators get: 100\\*80% - Commission = 64 BNB\n

    The rewards for motivating validators to vote for Fast Finality also comes from transaction fees. The specific rules can refer to BEP126

    If validators double sign, malicious vote or frequently offline, their staked BNB (not including BNB of users that delegated to them) can be slashed. The penalty depends on the severity of the violation.

    You can learn to see the revenue history from BitQuery\u2019s chart or a table of BscScan

    "},{"location":"bnb-smart-chain/validator/overview/#risks-for-validators","title":"Risks for Validators","text":"

    If validators attempt to cheat the system or violate the specifications, they may incur a penalty known as slashing.

    "},{"location":"bnb-smart-chain/validator/overview/#double-sign-slash","title":"Double Sign Slash","text":"

    Running your validator keys simultaneously on two or more machines will result in Double-Sign slashing. The penalty for double-sign slash:

    1. 200 staked BNB will be slashed for the validator.
    2. The double sign jail time is 30 days, preventing the malicious validator from participating in consensus until manual intervention is taken.

    Note: Rewards for submitting double-sign evidence: 5BNB. Anyone can submit a slashing request with the evidence of double sign, which should contain the 2 block headers with the same height and parent block, sealed by the offending validator.

    "},{"location":"bnb-smart-chain/validator/overview/#malicious-fast-finality-vote-slash","title":"Malicious Fast Finality Vote Slash","text":"

    Running your validators with the same consensus keys and bls voting keys concurrently on two or more machines will result in malicious vote slash. The penalty for malicious vote slash:

    1. 200 staked BNB will be slashed for the validator.
    2. The malicious vote jail time is 30 days, you can send an unjail transaction after the jail time to reactivate your validator.

    Note: Rewards for submitting Malicious Vote evidence: 5BNB. Anyone can submit a slash request with the evidence of malicious vote on BSC, which should contain the 2 votes, signed by the offending validator.

    "},{"location":"bnb-smart-chain/validator/overview/#downtime-slash","title":"Downtime Slash","text":"

    If your validator misses over 50 blocks in 24 hours, the blocking reward won\u2019t be given to you but will be shared among other validators. If your validator continues to miss more than 150 blocks within 24 hours, it will trigger the following penalty for being offline.

    1. 10 staked BNB will be slashed for the validator.
    2. The offline jail time is 2 days. This allows the validator to send an unjail transaction and resume as an active validator after 2 days.
    "},{"location":"bnb-smart-chain/validator/overview/#low-self-delegation-slash","title":"Low Self-Delegation Slash","text":"

    Validators must stake a minimum of 2000 BNB for self-delegation. If the self-delegated amount is less, the penalty is 2 days of jail time.

    "},{"location":"bnb-smart-chain/validator/run-val/","title":"Run BSC Validator - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/run-val/#run-bsc-validator","title":"Run BSC Validator","text":""},{"location":"bnb-smart-chain/validator/run-val/#validator-hardware-requirements","title":"Validator Hardware Requirements","text":""},{"location":"bnb-smart-chain/validator/run-val/#mainnet","title":"Mainnet","text":""},{"location":"bnb-smart-chain/validator/run-val/#testnet","title":"Testnet","text":""},{"location":"bnb-smart-chain/validator/run-val/#setup-validator-node","title":"Setup Validator Node","text":""},{"location":"bnb-smart-chain/validator/run-val/#1-install-bsc-fullnode","title":"1. Install BSC Fullnode","text":"

    Follow the instructions here to set up a full node.

    "},{"location":"bnb-smart-chain/validator/run-val/#2-prepare-accounts","title":"2. Prepare Accounts","text":"

    Two accounts require preparation before running a validator: the Consensus account and the BLS Vote account. Ensure these accounts match the corresponding ones when creating a new validator.

    "},{"location":"bnb-smart-chain/validator/run-val/#generate-consensus-address","title":"Generate Consensus Address","text":"

    To create a new mining consensus account, run this command and set a password for the account:

    geth account new --datadir ${DATA_DIR}\n

    If you already have a consensus account, skip this step. Save the password in a file named password.txt:

    echo {your-password for the consensus account} > password.txt\n
    "},{"location":"bnb-smart-chain/validator/run-val/#generate-bls-vote-address","title":"Generate BLS Vote Address","text":"

    To set up a new BLS account, use this command:

    geth bls account new --datadir ${DATA_DIR}\n

    If you already have a BLS vote key, you can create a BLS wallet and recover it with the keyfile using:

    geth bls account import ${KEY_FILE} --datadir ${DATA_DIR}\n

    To retrieve your bls address, run:

    geth bls account list --datadir ${DATA_DIR}\n

    Save the password in a file named blspassword.txt:

    echo {your-password for the BLS wallet} > blspassword.txt\n
    "},{"location":"bnb-smart-chain/validator/run-val/#3-start-validator-node","title":"3. Start Validator Node","text":"

    Warning: Please do not expose your RPC endpoints to public network!

    Start your validator using the command line below:

    geth --config ./config.toml --datadir ./node --syncmode snap -unlock {accounts to sign txs, including your mining account at least} --miner.etherbase {the address of your mining account} --password password.txt --blspassword blspassword.txt --mine --vote --allow-insecure-unlock --cache 18000\n
    "},{"location":"bnb-smart-chain/validator/run-val/#post-running","title":"Post Running","text":""},{"location":"bnb-smart-chain/validator/run-val/#1-monitor-node-status","title":"1. Monitor node status","text":"

    To get started quickly, run GethExporter in a Docker container.

    docker run -it -d -p 9090:9090 \\\n  -e \"GETH=http://mygethserverhere.com:8545\" \\\n  hunterlong/gethexporter\n

    "},{"location":"bnb-smart-chain/validator/run-val/#2-update-validator-profile","title":"2. Update validator profile","text":"

    You can submit a PullRequest to this repository to update your information: https://github.com/bnb-chain/validator-directory

    Reference: https://grafana.com/grafana/dashboards/6976

    "},{"location":"bnb-smart-chain/validator/run-val/#3-publish-validator-information","title":"3. Publish Validator Information","text":"

    Please submit a Pull Request to this repo https://github.com/bnb-chain/bsc-validator-directory

    This repository is a place for validator candidates to give potential delegators a brief introduction about your team and infrastructure, and present your ecosystem contributions.

    "},{"location":"bnb-smart-chain/validator/run-val/#4-stop-validating","title":"4. Stop Validating","text":"

    You can stop mining new blocks by sending commands in geth console

    Connect to your validator node with geth attach ipc:path/to/geth.ipc

    miner.stop()\n

    To resume validating,

    miner.start()\n
    "},{"location":"bnb-smart-chain/validator/run-val/#some-tips-tools","title":"Some Tips & Tools","text":""},{"location":"bnb-smart-chain/validator/run-val/#1run-backup-node","title":"1.Run backup node","text":"

    Backup node could help when your primary validator node encounters issues due to a variety of potential reasons, ensuring the continuity and reliability of your participation in the network.

    "},{"location":"bnb-smart-chain/validator/run-val/#2check-your-nodes-stability","title":"2.Check your node\u2019s stability","text":"

    There is a javascript in BSC repo to dump the slash status of each validator.

    cd <bsc>/cmd/jsutils\n# 1.To dump the slashes of the lates block:\nnode getslashcount.js --Rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce\n\n# 2.You may also specify the block number:\nnode getslashcount.js --Rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce --Num 39938351\n
    If your validator operates smoothly, you should expect minimal or even no penalties, known as \u201cslashes,\u201d on a daily basis. Generally speaking, if your validator incurs more than three slashes within a single day, it would be prudent to investigate the cause for this anomaly."},{"location":"bnb-smart-chain/validator/run-val/#3about-maintenance-mode","title":"3.About maintenance mode","text":"

    Should your validator incur 50 slashes, it will automatically transition into maintenance mode. It is imperative to promptly diagnose and rectify any issues with your node to prevent further penalties. Failure to do so may result in your node being placed in a more restrictive state, often referred to as \u201cjail.\u201d

    Upon successfully restoring your node\u2019s functionality, it is crucial to promptly exit maintenance mode to resume normal operations and avoid any unnecessary downtime or penalties.

    // note: replace \"0x75B851a27D7101438F45fce31816501193239A83\" with your validator's consensus address.\ngeth attach geth.ipc\nweb3.eth.sendTransaction({   from: \"0x75B851a27D7101438F45fce31816501193239A83\",   to: \"0x0000000000000000000000000000000000001000\",   data: \"0x04c4fec6\"})\n
    "},{"location":"bnb-smart-chain/validator/run-val/#4filter-out-peers-by-regex-pattern","title":"4.Filter out peers by regex pattern","text":"

    This functionality was introduced with version 1.4.6, primarily designed to identify and exclude peers that may present operational challenges, thereby preventing connections with them. For further details, please refer to this Pull Request: PR#2404.

    Generally, this feature is not necessary for regular operation. However, in the event that a release contains critical bugs and an immediate upgrade of all nodes to a stable version is not feasible, this feature can be employed to disconnect from peers running the problematic versions. This serves as a temporary solution to mitigate the impact of the bugs until a comprehensive upgrade can be performed.

    For example, if v1.4.9 has known issues, we wanna disconnect nodes of this version, you may update your config.toml and restart:

    [Node.P2P]\nPeerFilterPatterns = [\"Geth/v1.4.9.*\"]\n
    "},{"location":"bnb-smart-chain/validator/security/","title":"Secure BSC Validator - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/security/#secure-bsc-validator","title":"Secure BSC Validator","text":"

    Each BSC validator is encouraged to run its operations independently, as diverse setups increase the resilience of the network. Due to the high amount invested by validators it is highly essential to protect them against different DoS and DDoS attacks. In this section, we discuss the security mechanism adopted by BSC for its validators.

    "},{"location":"bnb-smart-chain/validator/security/#sentry-nodes-ddos-protection","title":"Sentry Nodes (DDOS Protection)","text":"

    Validators should ensure network resilience against denial of service attacks. One effective approach to reduce these risks is by organizing their network in a sentry node architecture. Sentry nodes, easily deployed and capable of IP address changes, operate in private IP space, shielding them from direct internet attacks. This setup guarantees that validator block proposals and votes reliably reach the network.

    To setup your sentry node architecture you can follow the instructions below:

    "},{"location":"bnb-smart-chain/validator/security/#1-setup-nodes","title":"1. Setup Nodes","text":"

    Construct a private network and establish trusted connections between the validator node and its sentry nodes. Refer to the fullnode guide for setting up your validator and sentry nodes. Avoid exposing your validator\u2019s RPC endpoints to the public network.

    "},{"location":"bnb-smart-chain/validator/security/#2-add-peers","title":"2. Add Peers","text":"

    Connect individual sentry nodes\u2019 console, execute admin.nodeInfo.enode command. This will provide you with the enode information for each node, as illustrated below.

    enode://f2da64f49c30a0038bba3391f40805d531510c473ec2bcc7c201631ba003c6f16fa09e03308e48f87d21c0fed1e4e0bc53428047f6dcf34da344d3f5bb69373b@[::]:30306?discport=0\n

    !!! Note: [::] will be interpreted as the localhost (127.0.0.1) address. If your nodes are within a local network, ensure to inspect each host machine to determine its IP using the ifconfig command. However, if your peers are outside the local network, you must be aware of your external IP address to form the enode URL correctly.

    Replace [::] with the correct node URL, copy the enode details, and add them to the config.toml file of the validator node like this:

    # make node hidden\nNoDiscovery = true\n# connect exclusively to sentry\nStaticNodes = [\"enode://f2da64f49c30a0038bba3391f40805d531510c473ec2bcc7c201631ba003c6f16fa09e03308e48f87d21c0fed1e4e0bc53428047f6dcf34da344d3f5bb69373b@[10.1.1.1]:30306\"]\n
    "},{"location":"bnb-smart-chain/validator/security/#3-confirm-connections","title":"3. Confirm Connections","text":"

    Connect to the validator\u2019s console, run admin.peers, and you will see the details of the sentry nodes you added.

    "},{"location":"bnb-smart-chain/validator/security/#firewall-configuration","title":"Firewall Configuration","text":"

    Geth utilizes different ports for various functions.

    It utilizes a listener (TCP) port and a discovery (UDP) port for P2P connections, typically configured to 30303. Ensure this port is open.

    The default JSON-RPC service port is TCP port 8545. To prevent unauthorized admin operations, refrain from exposing the JSON-RPC port externally.

    "},{"location":"bnb-smart-chain/validator/mev/builder-integration/","title":"Integration Guide for Builder - BSC MEV","text":""},{"location":"bnb-smart-chain/validator/mev/builder-integration/#integration-guide-for-builder","title":"Integration Guide for Builder","text":"

    The Builder API Specification defines the standard interface that builders should implement, while the specific implementation is left open to MEV API providers. The BNB Chain community offers a simple implementation example for reference.

    "},{"location":"bnb-smart-chain/validator/mev/builder-integration/#customize-builder","title":"Customize Builder","text":"

    Although the builder offers great flexibility, there are still some essential standards that must be followed:

    1. The builder needs to set up a builder account, which is used to sign the block bid and receive fees. The builder can ask for a tip (builder fee) on the block that it sends to the sentry. If the block is finally selected, the builder account will receive the tip.

    2. The builder needs to implement the mev_reportIssue API to receive the errors report from validators.

    3. In order to prevent transaction leakage, the builder can only send block bids to the in-turn validator.

    4. At most 3 block bids are allowed to be sent at the same height from the same builder.

    Here are some sentry APIs that may interest a builder:

    1. mev_bestBidGasFee. It will return the current most profitable reward that the validator received among all the blocks received from all builders. The reward is calculated as: gasFee*(1 - commissionRate) - tipToBuilder. A builder may compare the bestBidGasFee with a local one and then decide to send the block bid or not.

    2. mev_params. It will return the BidSimulationLeftOver,ValidatorCommission, GasCeil and BidFeeCeil settings on the validator. If the current time is after (except block time - BidSimulationLeftOver), then there is no need to send block bids any more; ValidatorCommission and BidFeeCeil helps the builder to build its fee charge strategy. The GasCeil helps a builder know when to stop adding more transactions.

    Builders have the freedom to define various aspects like pricing models for users, creating intuitive APIs, and define the bundle verification rules.

    "},{"location":"bnb-smart-chain/validator/mev/builder-integration/#setup-with-example-builder","title":"Setup with Example Builder","text":"

    Step 1: Find Validator Information

    For validators that open MEV integration, the public information is shown at bsc-mev-info. Builders can also provide information here to the validator.

    Step 2: Set up Builder.

    The builder must sign the bid using an account, such as the etherbase account specified in the config.toml file.

    [Eth.Miner.Mev]\nBuilderEnabled = true # open bid sending\nBuilderAccount = \"0x...\" # builder address which signs bid, usually it is the same as etherbase address\n

    Configure the validator node list, including the address of the validator and the public URL. The public URL refers to the sentry service.

    [[Eth.Miner.Mev.Validators]]\nAddress = \"0x23707D3D...6455B52B3\"\nURL = \"https://bsc-fuji.io\"\n\n[[Eth.Miner.Mev.Validators]]\nAddress = \"0x52825922...3A1A7A422\"\nURL = \"http://bsc-mathwallet.io\"\n

    Step 3: Publish information

    It is highly recommended to publish information in bsc-mev-info.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/","title":"FAQs - BSC MEV","text":""},{"location":"bnb-smart-chain/validator/mev/faqs/#faqs","title":"FAQs","text":""},{"location":"bnb-smart-chain/validator/mev/faqs/#1-why-is-the-mev-solution-important-for-the-bnb-chain-ecosystem","title":"1. Why is the MEV solution important for the BNB Chain ecosystem?","text":"

    BNB Chain\u2019s MEV solution leverages Proposer Builder Separation (PBS) architecture to foster a more transparent and fair block space market. Through PBS, users gain the power to select their preferred builder for transaction submission, while MEV rewards are equitably distributed among searchers, validators, builders, and BNB stakers. This approach promotes transparency, fairness, user choice, and network security. By distributing rewards across various roles, BNB Chain encourages wider participation and reduces the risk of centralization, to build a decentralized and inclusive blockchain ecosystem.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#2-do-builders-fetch-the-in-turn-proposers-gasceil-to-build-block","title":"2. Do builders fetch the in-turn proposer\u2019s GasCeil to build block\uff1f","text":"

    Yes, you could using RPC mev_params to query validator\u2019s MEV information before building block, it can help to 1) calculate a valid header with gas no more than GasCeil; 2) calculate the left bidding time by BidSimulationLeftOver; 3) calculate suitable builderFee by validatorCommission.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#3-how-does-the-validator-choose-the-best-bid","title":"3. How does the validator choose the best bid?","text":"

    The block reward is calculated as gasFee, the validator reward is calculated as gasFee*commissionRate - builderFee. Every time the validator receives a new bid, it will compare its reward with the existing best bid. If it has better block reward and validator reward, the new bid will go into simulation. If simulation succeeds before block sealing, it will be compared with local mined block reward. If the bid\u2019s block reward and validator reward are both superior to the local block, it will be sealed by the validator.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#4-who-can-become-the-builder","title":"4. Who can become the builder?","text":"

    BNB Chain is a permission-less ecosystem, anyone who implements the standard builder API could be the BNB Chain builder.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#5-where-can-i-find-the-bnb-chain-builders-information","title":"5. Where can I find the BNB Chain builders information?","text":"

    You can find the BNB Chain builders through a public builder info repo

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#6-how-many-validators-have-been-integrated-with-the-builders","title":"6. How many validators have been integrated with the builders?","text":"

    You can find the validators that has implemented the PBS solution from validator info repo

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#7-where-can-i-find-the-bnb-chain-mev-statistic-dashboard","title":"7. Where can I find the BNB Chain MEV statistic dashboard?","text":"

    You can view the MEV statistics from MEV Stats Dashboard

    "},{"location":"bnb-smart-chain/validator/mev/overview/","title":"Overview - BSC MEV","text":""},{"location":"bnb-smart-chain/validator/mev/overview/#bsc-mev-overview","title":"BSC MEV Overview","text":"

    The BSC network has introduced the Builder API Specification to establish a fair and unified MEV market. Previously, BSC clients lacked native support for validators to integrate with multiple MEV providers at once. The network became unstable because of the many different versions of the client software being used. The latest BSC client adopts the Proposer-Builder Separation model. Within this unified framework, several aspects of the BSC network have been improved:

    "},{"location":"bnb-smart-chain/validator/mev/overview/#what-is-mev-and-pbs","title":"What is MEV and PBS","text":"

    MEV, also known as Maximum (or Miner) Extractable Value, can be described as the measure of total value that may be extracted from transaction ordering. Common examples include arbitraging swaps on decentralized exchanges or identifying opportunities to liquidate DeFi positions. Maximizing MEV requires advanced technical expertise and custom software integrated into regular validators. The returns are likely higher with centralized operators.

    Proposer-builder separation(PBS) solves this problem by reconfiguring the economics of MEV. Block builders create blocks and submit them to the block proposer, and the block proposer simply chooses the most profitable one, paying a fee to the block builder. This means even if a small group of specialized block builders dominate MEV extraction, the reward still goes to any validator on the network.

    "},{"location":"bnb-smart-chain/validator/mev/overview/#how-it-works-on-bsc","title":"How it Works on BSC","text":"

    The figure above illustrates the basic workflow of PBS operating on the BSC network.

    A new component called Sentry has been introduced to enhance network security and account isolation. It assists proposers in communicating with builders and enables payment processing.

    "},{"location":"bnb-smart-chain/validator/mev/overview/#what-is-more","title":"What is More","text":"

    The PBS model on BSC differs in several aspects from its implementation on Ethereum. This is primarily due to\uff1a

    1. Different Trust Model. Validators in the BNB Smart Chain are considered more trustworthy, as it requires substantial BNB delegation and must maintain a high reputation. This stands in contrast to Ethereum, where becoming an Ethereum validator is much easier, the barrier to becoming a validator is very low (i.e., 32 ETH).

    2. Different Consensus Algorithms. In Ethereum, a block header is transferred from a builder to a validator for signing, allowing the block to be broadcasted to the network without disclosing the transactions to the validator. In contrast, in BSC, creating a valid block header requires executing transactions and system contract calls (such as transferring reward and depositing to the validator set contract), making it impossible for builders to propose the whole block.

    3. Different Blocking Time. With a shorter block time of 3 seconds in BSC compared to Ethereum\u2019s 12 seconds, designing for time efficiency becomes crucial.

    These differences have led to different designs on BSC\u2019s PBS regarding payment, interaction, and APIs. For more design philosophy, please refer to BEP322:Builder API Specification for BNB Smart Chain.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/","title":"Integration Guide for Validator - BSC MEV","text":""},{"location":"bnb-smart-chain/validator/mev/validator-integration/#integration-guide-for-validator","title":"Integration Guide for Validator","text":""},{"location":"bnb-smart-chain/validator/mev/validator-integration/#decison-make","title":"Decison Make","text":"

    When activating MEV functionality, validators encounter a mix of opportunities and challenges. Before enabling this feature, validators need to carefully evaluate these risk accordingly:

    1. More maintenance work. Apart from the validator, additional maintenance of the Sentry service and its related network components is required.

    2. Network risk. Due to Sentry service being exposed to the public network, it is inevitably susceptible to possible network attacks.

    3. Financial risk. Validators need to pay fees to builders, securely managing accounts is a crucial topic.

    After identifying these risks, let\u2019s begin the journey.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/#validator-topology","title":"Validator Topology","text":"

    It is suggested that to split the internal network into two part:

    1. Private network. The private network is isolated from the public network. All access to components within this network is strictly restricted. The Validator and Payment wallet are expected to be deployed within a private network environment.

    2. Nat network. The components in this network can communicate with the public internet under certain constraints, and the communication can be established through load balancers provided by various cloud platforms. Sentry service should be deployed within a NAT network environment. It is essential to configure appropriate safeguards on the network gateway to prevent DoS attacks and other potential threats.

    The validator should open its RPC access to the mev-sentry. The mev-sentry should open its RPC to the public network with a domain host. The information of validator should be registered in bsc-mev-info.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/#hardware-spec","title":"Hardware Spec","text":"

    Mev-Sentry: The recommended specifications for the mev-sentry machine are 2 CPUs and 4 GB of RAM.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/#preparation","title":"Preparation","text":"

    The BNB Chain community has maintained an open-source version of the Sentry service. You can clone the code repository from here.

    Before actually deploying the Sentry service, it is crucial to carefully consider and determine several key parameters:

    1. BidFeeCeil. This represents the maximum fee that a validator is willing to pay for a block proposed by a builder. When this value is 0, it signifies that the validator does not accept any charges from the builder.

    2. BidSimulationLeftOver. This parameter indicates how long before the block time the validator should cease simulating the blocks from the builder. It is generally advisable to set it to a few tens of milliseconds. Setting it too small may result in blocks being broadcast too late and subsequently discarded during network congestion.

    It is suggested to purchase a domain that is related to the moniker name of the validator. The builders will send requests through this domain. A BSC account should be created in advance as the payment account. No BNB is required in that account if BidFeeCeil is zero, otherwise, it needs to be ensured that there is enough balance in the account.

    Go to the bsc-mev-info repo to find more information about running builders which will be used during setup.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/#quick-setup","title":"Quick Setup","text":"

    Step 1: Setup Sentry.

    Deploy the sentry service according to the readme of sentry repo.

    Here are a few key points to highlight.

    Step 2: Change the Config of Validator.

    Upgrade the validators to version v1.4.x or later, add a few new sections in the config.toml. Example:

      [Eth.Miner.Mev]\n  Enabled = true # open bid receiving\n  ValidatorCommission = 100 # validator claim 1% from block reward\n  BidSimulationLeftOver = 50000000 # 50ms, the time left for bid simulation\n  SentryURL = \"http://bsc-mev-sentry.io\" # it is used for the validator to access the sentry, it should be a private URL or IP:Port.\n\n  # Find builders in [bsc-mev-info](https://github.com/bnb-chain/bsc-mev-info)\n\n  [[Eth.Miner.Mev.Builders]]\n  Address = \"0x45EbEBe8...664D59c12\" # builder address which validator is willing to receive bid from\n\n  [[Eth.Miner.Mev.Builders]]\n  Address = \"0x980A75eC...fc9b863D5\" # builder address which validator is willing to receive bid from\n

    Step 3: Publish information

    It is highly recommended to publish information in bsc-mev-info so other builders can find it.

    "},{"location":"join-ecosystem/","title":"Index","text":"Join BNB Ecosystem There are several ways to share your project with BNB Chain Ecosystem or seeking for cooperations. We want to make it as easy as possible for prjects to get more exposure in BNB Chain Ecosystem or ask for support from the team. Below is the guideline that we ask projects to follow so that we can get achieve this efficiently. DappBay

    Discover top dApps built on BNB Smart Chain, opBNB & BNB Greenfield, the leading blockchain scaling solution.

    Developer Tools

    List your project on the tool page or find the right tools for your development.

    Electrical Capital

    Add your project to BNB ecosystem and contribute on BNB chain developer data

    "},{"location":"join-ecosystem/platforms/dappbay/","title":"Submit Project on DappBay & DappRadar","text":""},{"location":"join-ecosystem/platforms/dappbay/#submit-project-on-dappbay-dappradar","title":"Submit Project on DappBay & DappRadar","text":"

    DappBay & DappRadar are 2 hubs for users to discover top dApps built on BNB Ecosystem. Projects are encouraged to submit dApp informations to them to get full exposure to users.

    Submit to DappBay DappBay currently supports BNB Smart Chain, opBNB and BNB Greenfield. It also provides risk scanning for those dapps to ensure safety for the ecosystem. You can follow below steps to submit your project:

    1. Connect to dappbay with your wallet.
    2. Fill in the form by Clicking on Submit-Dapps.
    3. Submit the updates by repeating steps 1-2 whenever there is a change of your project, including logo, description, github repo, contract address, ect.

    If you find anything to improve, pls contact us on BNB Chain official discord.

    Submit to DappRadar DappRadar is a Dapp Store for user to explore NFTs, NFT Marketplaces, Blockchain Games, De-Fi, Dapps On The Blockchain. It currently supports BNB Smart Chain and opBNB. You can follow below steps to submit your project:

    1. Login DappRadar in the way you prefer.
    2. Fill in the form by Clicking on Submit-Dapp.
    3. Submit the updates by repeating steps 1-2 whenever there is a change of your project, including logo, description, github repo, contract address, ect.
    "},{"location":"join-ecosystem/platforms/dappbay/#submit-project-for-cooperations","title":"Submit Project for Cooperations","text":"

    For projects seeking for cooperations, you could submit your project details in official discord channel submit-project. The team will review your submission and contact you if we find a fit.

    "},{"location":"join-ecosystem/platforms/dev-tool/","title":"Submit Tools on Developers Tool","text":""},{"location":"join-ecosystem/platforms/dev-tool/#submit-tools-on-developers-tool","title":"Submit Tools on Developers Tool","text":"

    Developers Tool is a developer tooling landscape which collects toolings for developers to build on BSC, opBNB and Greenfield. Contributions on this page will make developers find your project and integrate it in their work more easily.

    Steps

    1. Prepare basic information of your project: description, website, logo, supported chain, etc.

    2. Choose the tag (e.g. Defi, AI, Game, etc) and Category (e.g. Wallet, Dex, Marketplace, etc) your project belongs to.

    3. Submit the above information by raising a Github PR here. For more information, please refer to this Guide.

    "},{"location":"join-ecosystem/platforms/electrical-capital/","title":"Contribute on Developer Data","text":""},{"location":"join-ecosystem/platforms/electrical-capital/#contribute-on-developer-data","title":"Contribute on Developer Data","text":"

    To contribute on BNB Chain developer activity, projects should add their github repositories to the community-supported developer tracking tool Crypto Ecosystems, which will track your developer activity and include it in BNB Chain developer statistics.

    Steps

    1. Prepare your github repository.

    2. Create a toml file under ecosystems for your dapp.

    3. Add the created toml file to BNB Chain subecosystem

    4. For more details, please follow this Guide to add your repository to BNB Chain ecosystem. Here is an example for your reference.

    "},{"location":"showcase/game/minigame/","title":"Showcase - Creating Telegram BNB Mini Apps","text":""},{"location":"showcase/game/minigame/#creating-telegram-bnb-mini-apps-a-how-to-guide-for-developers","title":"Creating Telegram BNB Mini Apps: A How-to Guide for Developers","text":"

    Launching decentralized applications on Telegram has become increasingly popular due to it giving users access to mini apps and games without requiring them to install additional software, providing an easy way for users to interact with blockchain-based services. This lowers the barriers to entry for users and makes it simple for developers to distribute their apps to a large Telegram audience.

    This guide will walk you through the steps for building a basic Telegram mini app on BNB in just a few hours. By the end, you will have the skills to launch your own BNB project on Telegram\u2019s open platform. Whether you are a blockchain expert or just starting out, this tutorial aims to demystify decentralized app creation. So let\u2019s get started building on BSC! The possibilities are endless when you master Telegram mini apps.

    Note: This guide only provides a high level overview of the steps that may be involved in creating telegram BNB miniapp. For a detailed guide, visit the youtube demo or the github repo.

    "},{"location":"showcase/game/minigame/#introduction-to-telegram-bnb-mini-apps","title":"Introduction to Telegram BNB Mini Apps","text":""},{"location":"showcase/game/minigame/#what-are-telegram-mini-apps","title":"What are Telegram Mini Apps?","text":"

    Telegram Mini Apps are lightweight web apps that run inside Telegram chats. They allow developers to create social experiences, games, marketplaces, and other services that tap into Telegram\u2019s features and large audience.

    Catizen\u2019s play-to-earn and Hamster Kombat\u2019s tap-to-earn, what\u2019s the next big thing for Telegram mini games?

    Mini Apps load instantly, work offline, and don\u2019t need to be installed. They can use Telegram login, payments, storage and more. Developers can build Mini Apps using HTML, CSS and JavaScript. How to Create a Mini App To create a Mini App, you need:

    Your web app will run in an iframe and communicate with the user\u2019s Telegram app using the Telegram Bridge. The Bridge exposes the Telegram API and passes messages between your web app and the user\u2019s Telegram app.

    "},{"location":"showcase/game/minigame/#mini-app-types","title":"Mini App Types","text":"

    There are two main types of Mini Apps:

    "},{"location":"showcase/game/minigame/#inline-apps","title":"Inline Apps","text":"

    Inline Apps show up as results when a user types the bot\u2019s username followed by a query. The user taps an app result to launch the Mini App. Inline Apps are great for:

    "},{"location":"showcase/game/minigame/#direct-link-apps","title":"Direct Link Apps","text":"

    Users can open a Direct Link App just by tapping a link. Direct Link Apps are aware of the current chat context and support shared, collaborative experiences. Direct Link Apps are ideal for:

    The mini app can also be launched from a keyboard button, from an inline button, and from the bot menu button. Refer to the official Telegram mini app documentation.

    "},{"location":"showcase/game/minigame/#step-by-step-guide-to-creating-a-bnb-mini-app","title":"Step-by-Step Guide to Creating a BNB Mini App","text":"

    With the power of Telegram behind them, Mini Apps open up countless new opportunities for creativity and building engaging experiences on the platform. The potential for Mini Apps is huge, and this is just the beginning.

    "},{"location":"showcase/game/minigame/#create-a-telegram-bot","title":"Create a Telegram Bot","text":"

    To get started, you will need to create a Telegram bot. Visit the @BotFather bot and enter /newbot to create a new bot. You will receive an API token for your bot. Keep this token private as it will allow you to control your bot.

    "},{"location":"showcase/game/minigame/#connect-the-webapp-to-your-bot","title":"Connect the Webapp to Your Bot","text":"

    Next, you need to connect your webapp to the Telegram bot. Use the /newapp command in the @BotFather bot by selecting your bot. Provide details such as the app name, description, photo, etc. Finally, enter the URL of your webapp. Your mini app will now appear in the Telegram app and can be launched by users.

    "},{"location":"showcase/game/minigame/#additional-capabilities","title":"Additional Capabilities","text":"

    Mini apps opened from a direct link have limited capabilities. They cannot read or send messages on behalf of the user. However, they support cooperative and multiplayer features within the current chat context. Users must redirect to inline mode to actively pick a result in order to send messages.

    Mini apps are powerful tools for creating fully-fledged web services, team collaborations, multiplayer games, and more. The possibilities are endless.

    "},{"location":"showcase/game/minigame/#turning-your-mini-app-into-a-game","title":"Turning Your Mini App Into a Game","text":"

    To transform your Mini App into an engaging game on Telegram, you must first register a bot with @BotFather and create a Mini App as outlined in the previous section. Once you have a functioning Mini App, you can then convert it into a game by using Telegram\u2019s Game API.

    "},{"location":"showcase/game/minigame/#difference-between-mini-apps-and-mini-games","title":"Difference Between Mini Apps and Mini Games","text":"

    Mini games build upon mini apps by providing additional information like:

    To create a mini game, use the /newgame command and configure callback functions to return your game\u2019s URL.

    "},{"location":"showcase/game/minigame/#register-a-game-with-gamebot","title":"Register a Game with @GameBot","text":"

    The first step is to register your game with @BotFather. Send the /newgame command to @BotFather, and provide the required details including:

    Implement Callbacks You must implement callback functions in your code to handle interactions with the Telegram Game API. Specifically, you need a callback_query() callback which will receive updates from Telegram when a user clicks an inline button in your game. Within this callback, you should check the callback ID to determine which button was clicked. You may implement multiple inline keyboard buttons for the game, but note that the first button must always launch the game.

    "},{"location":"showcase/game/minigame/#share-your-game","title":"Share Your Game","text":"

    Once registered, your game will receive a shareable game URL and a game code which players can enter to launch the game. You can share this URL and code on your website, social media, and within Telegram chats to spread your game to new players.

    "},{"location":"showcase/game/minigame/#consider-a-leaderboard-optional","title":"Consider a Leaderboard (Optional)","text":"

    To increase engagement and competition, you can implement an in-game leaderboard where players can see the top scores. You will need to store player scores in a database, and return the leaderboard data within your callbacks. Leaderboards are an optional feature, but can greatly enhance the popularity and longevity of Telegram games.

    By following these steps, you can build fully-featured games within Telegram using JavaScript and the Telegram Game API. Games are an exciting way to engage users, and the possibilities for multiplayer, social, and interactive gaming experiences on Telegram are endless. Let your creativity run wild, and build the next hit game on Telegram!

    "},{"location":"showcase/game/minigame/#faqs-about-telegram-bnb-mini-apps","title":"FAQs About Telegram BNB Mini Apps","text":""},{"location":"showcase/game/minigame/#what-are-the-main-features-of-telegram-bnb-mini-apps","title":"What are the main features of Telegram BNB Mini Apps?","text":"

    Telegram BNB Mini Apps allow developers to build decentralized applications on BSC or opBNB that can be accessed directly within Telegram. Some of the key features include:

    "},{"location":"showcase/game/minigame/#what-are-the-differences-between-mini-apps-and-bots","title":"What are the differences between Mini Apps and Bots?","text":"

    Telegram Mini Apps are web apps that run within the Telegram app, while Telegram Bots are automated accounts controlled via API. Some key differences include:

    "},{"location":"showcase/game/minigame/#what-languages-and-frameworks-can-i-use-to-build-a-mini-app","title":"What languages and frameworks can I use to build a Mini App?","text":"

    You can build Telegram Mini Apps using:

    "},{"location":"showcase/game/minigame/#summary","title":"Summary","text":"

    Telegram mini apps and mini games provide developers with exciting new ways to engage users. By following the step-by-step guide outlined here, you can leverage Telegram\u2019s massive user base to share your own interactive web apps and games. Consider the possibilities - multiplayer experiences, chatbots, productivity tools and more are now just a few lines of code away. As Telegram continues expanding its platform, developers have an opportunity to be on the cutting edge and reach an audience of millions. So don\u2019t wait, get started building your own mini app today! With the right idea and a bit of effort, you could create the next viral sensation on Telegram.

    "},{"location":"showcase/identity/attestation-dev/","title":"Get Started - Attestation","text":""},{"location":"showcase/identity/attestation-dev/#get-started-attestation","title":"Get Started - Attestation","text":""},{"location":"showcase/identity/attestation-dev/#creating-on-chain-attestations","title":"Creating On-chain Attestations","text":"

    The attest function enables you to confidently create an on-chain attestation for a specific schema. This powerful function accepts an object with the following properties:

    This function gracefully returns a Promise that resolves to the UID of the newly created attestation.

    import { BAS, SchemaEncoder } from \"@bnb-attestation-service/bas-sdk\";\n\nconst bas = new BAS(BASContractAddress);\nbas.connect(signer);\n\n// Initialize SchemaEncoder with the schema string\nconst schemaEncoder = new SchemaEncoder(\"uint256 eventId, uint8 voteIndex\");\nconst encodedData = schemaEncoder.encodeData([\n  { name: \"eventId\", value: 1, type: \"uint256\" },\n  { name: \"voteIndex\", value: 1, type: \"uint8\" },\n]);\n\nconst schemaUID = \"0xb16fa048b0d597f5a821747eba64efa4762ee5143e9a80600d0005386edfc995\";\n\nconst tx = await bas.attest({\n  schema: schemaUID,\n  data: {\n    recipient: \"0xFD50b031E778fAb33DfD2Fc3Ca66a1EeF0652165\",\n    expirationTime: 0,\n    revocable: true,// Be aware that if your schema is not revocable, this MUST be false\n    data: encodedData,\n  },\n});\n\nconst newAttestationUID = await tx.wait();\n\nconsole.log(\"New attestation UID:\", newAttestationUID);\n
    "},{"location":"showcase/identity/attestation-dev/#creating-off-chain-attestations-without-saving-to-greenfield","title":"Creating Off-chain Attestations without Saving to GreenField","text":"

    To generate an off-chain attestation, you can confidently utilize the signOffchainAttestation function offered by the Off-chain class in the BAS SDK. Here\u2019s an example:

    import { SchemaEncoder } from \"@bnb-attestation-service/bas-sdk\";\n\nconst offchain = await bas.getOffchain();\n\n// Initialize SchemaEncoder with the schema string\nconst schemaEncoder = new SchemaEncoder(\"uint256 eventId, uint8 voteIndex\");\nconst encodedData = schemaEncoder.encodeData([\n  { name: \"eventId\", value: 1, type: \"uint256\" },\n  { name: \"voteIndex\", value: 1, type: \"uint8\" },\n]);\n\n// Signer is an ethers.js Signer instance\nconst signer = new ethers.Wallet(privateKey, provider);\n\nconst offchainAttestation = await offchain.signOffchainAttestation({\n  recipient: '0xFD50b031E778fAb33DfD2Fc3Ca66a1EeF0652165',\n// Unix timestamp of when attestation expires. (0 for no expiration)\n  expirationTime: 0,\n// Unix timestamp of current time\n  time: 1671219636,\n  revocable: true,// Be aware that if your schema is not revocable, this MUST be false\n  version: 1,\n  nonce: 0,\n  schema: \"0xb16fa048b0d597f5a821747eba64efa4762ee5143e9a80600d0005386edfc995\",\n  refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n  data: encodedData,\n}, signer);\n\nThis function will confidently generate an attestation object off-chain, which will be signed and contain the UID, signature, and attestation data. You can confidently share this object with the intended recipient or confidently store it for future use.\n
    "},{"location":"showcase/identity/attestation-dev/#creating-off-chain-attestation-and-saving-to-greenfield","title":"Creating Off-chain Attestation and Saving to GreenField","text":"

    To generate an off-chain attestation and save the result to GreenField Storage, you can confidently utilize the attestOffChain function offered by the BAS SDK. Here\u2019s an example:

      const offchain = await bas.getOffchain();\n\n  // Use wallet or client to ensure the chain is BNB\n  // [WARN]: should call an async function\n  await shouldSwitchNetwork(chains[1].id); // BNB chainId\n\n  // Attest offchain\n  const attestation = await attestOffChain({\n    schemaStr: attestParams.schemaStr,\n    schemaUID: attestParams.schemaUID,\n    data: attestParams.data,\n    recipient: attestParams.recipient,\n    revocable: attestParams.revocable,\n  });\n\n  const attestationUID = attestation.uid;\n\n  // Use wallet or client to ensure the chain is Greenfield Chain\n  await shouldSwitchNetwork(chains[0].id);\n  const provider = await connector?.getProvider({ chainId: chains[0].id });\n\n  BigInt.prototype.toJSON = function () {\n    return this.toString();\n  };\n\n  // Encode the attestation object into blob to store on the Greenfield Storage\n  const str = JSON.stringify(attestation);\n  const bytes = new TextEncoder().encode(str);\n  const blob = new Blob([bytes], {\n    type: \"application/json;charset=utf-8\",\n  });\n\n  let res;\n  try {\n    // Use GreenField SDK to store the attestation\n    res = await gfClient.createObject(\n      provider,\n      new File([blob], `${attestParams.schemaUID}.${attestationUID}`),\n      attestParams.isPrivate || true\n    );\n  } catch (err: any) {\n    console.log(err);\n    alert(err.message);\n  }\n

    This function will generate an attestation object off-chain. The attestation object will be signed and will contain the UID, signature, and attestation data. Similar to the previous function, you can also save it to greenfield storage and set the access according to your preferences.

    "},{"location":"showcase/identity/attestation-dev/#more-use-cases","title":"More Use Cases","text":"

    On-chain attestations will enable a powerful new range of web3 applications, including:

    And many more!

    "},{"location":"showcase/identity/attestation-dev/#resources","title":"Resources","text":""},{"location":"showcase/identity/attestation/","title":"Showcase - BNB Attestation Service","text":""},{"location":"showcase/identity/attestation/#bnb-attestation-service","title":"BNB Attestation Service","text":""},{"location":"showcase/identity/attestation/#what-is-attestation","title":"What is attestation?","text":"

    Attestations are digital signatures on structured data used to build more trust on-chain.

    "},{"location":"showcase/identity/attestation/#bnb-attestation-servicebas","title":"BNB Attestation Service(BAS)","text":"

    The BNB Attestation Service (BAS) is an infrastructure built on the BNB ecosystem for generating attestation to verify information. BAS assists users in on-chain or off-chain verification, allowing them to assert ownership of attestation by storing them in Greenfield. This approach ensures data privacy and access control.

    BAS serves as a standard and infrastructure for generating arbitrary attestations. Anyone can define any attestation in BAS along with its resolver. BAS supports the generation of on-chain/off-chain attestations, and by storing off-chain attestations in Greenfield, users gain ownership, ensure attestation privacy, and implement access control.

    "},{"location":"showcase/identity/attestation/#core-components-of-bas","title":"Core Components of BAS","text":"

    Checkout the smart contracts here.

    "},{"location":"showcase/identity/attestation/#types-of-attestations","title":"Types of attestations","text":"

    Attestations can be made either onchain or offchain. While onchain attestations are stored directly on the BNBChain, offchain attestations reside outside of it, often in decentralized storage solutions like Greenfield. Both methods have their unique advantages, and the choice largely depends on the specific requirements of the use case.

    Learn about the idfference between on-chain and off-chain difference here.

    "},{"location":"showcase/identity/attestation/#on-chain-attestation-record","title":"On-Chain Attestation Record","text":"

    Users can clearly view the structure of an on-chain attestation on BASCAN.

    "},{"location":"showcase/identity/attestation/#offchain-attestation-record","title":"OffChain Attestation Record","text":"

    Here\u2019s an off-chain attestation record. Unlike the on-chain record, this attestation is public, and the server is unaware of it. Users can share the attestation URL with others to decode the data or publish it to GreenField. Once published or pinned to GreenField, the status icon will switch to \u201cpublic.\u201d

    "},{"location":"showcase/identity/attestation/#use-cases-of-attestation","title":"Use Cases of Attestation","text":""},{"location":"showcase/identity/attestation/#kyc","title":"KYC","text":"

    Combined BAS with zero-knowledge proofs, zkPass uses three-party TLS and zero-knowledge (ZK) technology to create zero-knowledge proofs of user\u2019s real-world assets or actions directly in your browser. This ensures privacy by not oversharing your data and not requiring API authorizations. ZKPass is a private data protocol using affordable zero-knowledge technology. You can learn more about the use case in this blog.

    "},{"location":"showcase/identity/attestation/#developer-on-chain-reputation","title":"Developer on-chain reputation","text":"

    Aspecta ID integrates with the BAS to create and verify on-chain attestations of developers\u2019 achievements and activities, ensuring transparency, security, and trust in digital identity management. This partnership allows Aspecta to offer a tamper-proof and verifiable record of developers\u2019 skills and contributions, enhancing interoperability and trust within the AI and blockchain ecosystems. By leveraging BAS, Aspecta provides developers with a robust platform to authenticate their credentials, making their professional profiles more credible and secure. You can learn more about the use case in this blog.

    "},{"location":"showcase/identity/did/","title":"Showcase - Decentralized Identity","text":""},{"location":"showcase/identity/did/#decentralized-identity","title":"Decentralized Identity","text":""},{"location":"showcase/identity/did/#what-is-decentralized-identity","title":"What is Decentralized Identity?","text":"

    Identity, in both the digital and physical worlds, serves as a means of distinguishing and authenticating individuals and entities.

    Digital Identity:

    Decentralized Identifier (DID):

    "},{"location":"showcase/identity/did/#how-are-decentralized-identities-secured","title":"How are decentralized identities secured?","text":"

    A crucial aspect of securing decentralized identities is cryptography. In cryptography, private keys are known only to their owners, while public keys are widely distributed. This pairing serves two main purposes. First, it enables authentication, allowing the public key to verify that a message was sent by the holder of the corresponding private key. Second, it facilitates encryption, ensuring that only the holder of the paired private key can decrypt a message encrypted with the public key.

    "},{"location":"showcase/identity/did/#benefits-of-decentralized-identity","title":"Benefits of decentralized identity","text":""},{"location":"showcase/identity/did/#decentralized-identity-use-cases","title":"Decentralized Identity Use Cases","text":"Industry Traditional Process Problems/Risks Verifiable Credentials Solution Supply chain Utilizes physical IDs and documents to prove compliance, leading to inefficiencies. Documents can be easily falsified and are challenging to authenticate. The manual verification process is slow and error-prone. Unapproved and non-compliant medical supplies can enter the market, endangering public health. Verifiable Credentials are tamper-proof and can be verified instantly without needing to contact the issuer, greatly reducing time and costs. Finance To access financial services, individuals must undergo compliance screening by submitting personal details in physical form, which are stored in large databases and shared with multiple third parties for KYC and credit checks. Individuals have no control over the security, sharing, and access of their data by third parties. Credentials are cryptographically secured, tamper-proof, and can be verified, ensuring data integrity and security. Healthcare Employers manually verify paper-based licenses and certificates for healthcare providers. Traditional verification processes take weeks or months, delaying the filling of essential healthcare positions. Medical licenses can be issued as digital credentials by regulatory organizations, allowing healthcare providers to easily share them for immediate verification by hospitals, clinics, or medical departments where they seek employment."},{"location":"showcase/identity/dns-dev/","title":"Get Started - SpaceID","text":""},{"location":"showcase/identity/dns-dev/#get-started-spaceid","title":"Get Started - SpaceID","text":""},{"location":"showcase/identity/dns-dev/#how-to-resolve-a-name-using-the-space-id-sdk","title":"How to Resolve a Name Using the Space ID SDK","text":""},{"location":"showcase/identity/dns-dev/#step-1-setup-your-project","title":"Step 1: Setup Your Project","text":"
    1. Install Node.js and npm Ensure you have Node.js and npm installed. You can download them from Node.js official website.

    2. Create a New Project Open your terminal and create a new project directory:

    mkdir spaceid-tutorial\ncd spaceid-tutorial\nnpm init -y\n
    3. Install the Space ID SDK Install the Space ID SDK package using npm:
    Copy code\nnpm install @spaceid/sdk\n
    "},{"location":"showcase/identity/dns-dev/#step-2-write-the-code-to-resolve-a-name","title":"Step 2: Write the Code to Resolve a Name","text":"
    1. Create a JavaScript File Create a file named resolveName.js in your project directory.

    2. Import the Space ID SDK At the top of resolveName.js, import the Space ID SDK:

    const { SpaceID } = require('@spaceid/sdk');\n
    3. Initialize the Space ID SDK Initialize the SDK with the necessary parameters:
    const spaceId = new SpaceID({\n    endpoint: 'https://api.spaceid.io', // API endpoint\n    apiKey: 'your_api_key' // Replace with your actual API key\n});\n
    1. Resolve a Name Write a function to resolve a name using the SDK:
    async function resolveName(name) {\n    try {\n        const result = await spaceId.resolveName(name);\n        console.log(`Address for ${name}: ${result.address}`);\n    } catch (error) {\n        console.error('Error resolving name:', error);\n    }\n}\n
    1. Call the Function Call the resolveName function with a sample name:
    resolveName('example.eth');\n
    "},{"location":"showcase/identity/dns-dev/#step-3-run-the-code","title":"Step 3: Run the Code","text":"
    1. Run the Script In your terminal, run the script:
    node resolveName.js\n
    2. View the Result If everything is set up correctly, you should see the resolved address for the provided name in the terminal output."},{"location":"showcase/identity/dns-dev/#example-code","title":"Example Code","text":"

    Here\u2019s the complete code for resolveName.js:

    const { SpaceID } = require('@spaceid/sdk');\n\nconst spaceId = new SpaceID({\n    endpoint: 'https://api.spaceid.io',\n    apiKey: 'your_api_key'\n});\n\nasync function resolveName(name) {\n    try {\n        const result = await spaceId.resolveName(name);\n        console.log(`Address for ${name}: ${result.address}`);\n    } catch (error) {\n        console.error('Error resolving name:', error);\n    }\n}\n\nresolveName('example.eth');\n
    Replace \u2018your_api_key\u2019 with your actual API key and \u2018example.eth\u2019 with the name you want to resolve. You can read more in this blog."},{"location":"showcase/identity/dns/","title":"Showcase - Decentralized Naming Service","text":""},{"location":"showcase/identity/dns/#decentralized-naming-service","title":"Decentralized Naming Service","text":""},{"location":"showcase/identity/dns/#traditional-dns-vs-decentralized-naming-service","title":"Traditional DNS vs Decentralized Naming Service","text":"

    Traditional Domain Name System (DNS) and decentralized naming services like Ethereum Name Service (ENS) serve similar purposes but differ significantly in their underlying structures and control mechanisms. Traditional DNS translates human-readable domain names into IP addresses, enabling users to access websites easily. It is managed by centralized authorities, such as ICANN, which oversee the domain registration and resolution process. This centralization can lead to vulnerabilities, such as censorship, single points of failure, and control by a few entities.

    In contrast, decentralized naming services like ENS operate on blockchain technology, distributing control among network participants. ENS maps human-readable names to Ethereum addresses and other resources using smart contracts, ensuring that no single entity has overarching control. This decentralized approach enhances security, reduces the risk of censorship, and provides greater resilience against failures, aligning with the principles of trustlessness and user sovereignty inherent in blockchain ecosystems.

    "},{"location":"showcase/identity/dns/#spaceid","title":"SpaceID","text":""},{"location":"showcase/identity/dns/#overview","title":"Overview","text":"

    Space ID offers a universal namespace for blockchain, enabling users to register and manage domain names across different blockchains. It enhances cross-chain interoperability and simplifies user identification across the Web3 ecosystem. This project supports a broad range of applications, from crypto trading to token lending and NFT minting, showcasing a versatile approach to decentralized digital identities.

    "},{"location":"showcase/identity/dns/#how-spaceid-works","title":"How SpaceID works","text":"

    SPACE ID aims to create a universal name service network that connects decentralized identities with the physical and digital worlds. It is progressing toward becoming a comprehensive digital identity solution for Web3. Read the details here

    "},{"location":"showcase/identity/dns/#key-features-of-spaceid","title":"Key features of SpaceID","text":"

    Multi-Chain Name Service

    Among the top priorities of SPACE ID is supporting more blockchains and top-level domains (TLDs). Unlike SPACE ID 1.0, whose main emphasis was on .bnb Name Service, SPACE ID 2.0 instead focuses on multi-chain name service. SPACE ID has reached out to various blockchains for partnership discussions, and expects its ecosystem to flourish with time.

    Web3 Name SDK & API

    SPACE ID aims to streamline web3 services through the use of a single SDK to assist in the building of DApps. This saves developers time, since they don\u2019t have to work with multiple protocols and be encumbered with issues of blockchain incompatibility. This vision is being realized by adding an all-in-one API over the SDK, allowing current and future partners to seamlessly integrate their web3 services with their unified Web3 Name SDK.

    "},{"location":"showcase/identity/dns/#benefits-of-dns","title":"Benefits of DNS","text":""},{"location":"showcase/identity/dns/#use-case-of-spaceid","title":"Use Case of SpaceID","text":""},{"location":"showcase/wallet/in-app-wallet/","title":"Showcase - Thirdweb Wallet SDK Solution","text":""},{"location":"showcase/wallet/in-app-wallet/#service-plan","title":"Service plan","text":"

    Developers can choose between two service plans tailored to their needs:

    1. Free Plan: Offers basic functionalities and limited access to Thirdweb services.
    2. Pro Plan: Provides advanced features, priority support, and expanded usage limits.

    "},{"location":"showcase/wallet/in-app-wallet/#sdk-key-creation","title":"SDK Key Creation","text":"

    To utilize Thirdweb services, developers need to create an SDK key. This key allows integration of the Thirdweb SDK into their applications, enabling various blockchain functionalities.

    "},{"location":"showcase/wallet/in-app-wallet/#services-of-thirdweb","title":"Services of Thirdweb","text":"

    1. Storage Service

    2. In-App Wallet (Wallet as a Service)

    3. Account Abstraction

    4. Third-Party Bundler and Paymaster Integration

    "},{"location":"showcase/wallet/in-app-wallet/#supported-chains","title":"Supported Chains","text":"Chain mainnet testnet BSC Y Y opBNB Y N"},{"location":"showcase/wallet/in-app-wallet/#typical-example-in-react-app","title":"Typical example in React app","text":"

    https://portal.thirdweb.com/connect/account-abstraction/guides/react

    "},{"location":"zkbnb/","title":"zkBNB","text":"zkBNB

    zkBNB is the launchpad to achieve infinite scaling for all things Web3 and GameFi. It offers incredible scalability, Layer-1 level security, and frictionless developer experience to build dApps that can onboard the next billion users.

    Architecture

    zkBNB is a zero-knowledge scalability solution

    Resources

    Providing a Wealth of Resources for Building zkBNB

    "},{"location":"zkbnb/overview/","title":"zkBNB Overview - zkBNB","text":""},{"location":"zkbnb/overview/#what-is-zkbnb","title":"What is zkBNB?","text":"

    The zkBNB is an infrastructure for developers that helps them to build large scale BSC-based apps with higher throughput and much lower or even zero transaction fees.

    zkBNB is built on zk-Rollup architecture. zkBNB bundle (or \u201croll-up\u201d) hundreds of transactions off-chain and generates cryptographic proof. These proofs can come in the form of SNARKs (succinct non-interactive argument of knowledge) which can prove the validity of every single transaction in the Rollup Block.

    "},{"location":"zkbnb/overview/#problems-zkbnb-solves","title":"Problems zkBNB solves","text":"

    Today BSC is experiencing network scalability problems and the core developer has proposed to use sidechains in their Outlook 2022 paper to solve this problem because these sidechains can be designed for much higher throughput and lower gas fees.

    The BEP100 propose a modular framework for creating BSC-compatible side chains and connect them by native relayer hub. The security of native relayer hub is guaranteed by the side chain.

    According to the analysis of chainalysis, bridges are now a top target for the hackers and attacks on bridges account for 69% of total funds stolen in 2022. zkBNB can perfectly solve the problem! Thanks to zkSNARK proofs, zkBNB share the same security as BSC does.

    "},{"location":"zkbnb/overview/#what-are-the-key-features-of-zkbnb","title":"What are the key features of zkBNB?","text":"

    BNB achieves the following goals:

    (BEP721 token must be created in zkBNB in order to transfer from L1 to L2)

    Note: Full Exit and Exodus Exit are two different types of functionalities on zkBNB. Full exit is just about user can click a button and withdraw all his assets in one go. Exodus exit is about in emergency situation, say the whole zkBNB is down, user can still withdraw all this assets.

    "},{"location":"zkbnb/resources/","title":"Resources - zkBNB","text":""},{"location":"zkbnb/resources/#resources","title":"Resources","text":""},{"location":"zkbnb/resources/#repos","title":"\ud83d\udcd4 Repos","text":""},{"location":"zkbnb/resources/#building-dapps-on-zkbnb","title":"\ud83d\udc68\u200d\ud83d\udd27 Building Dapps on zkBNB","text":"

    Start building dapps to create value based on the data assets and their related economy. - Fund your zkBNB Wallet (Coming Soon\u23f0) - Build a dapp with zkBNB API (Coming Soon\u23f0)

    "},{"location":"zkbnb/resources/#help-support","title":"\ud83d\ude4b\u200d\u2640\ufe0f Help & Support","text":"

    Check out the zkBNB Developer Discord for technical support. (TBA \ud83d\udce2)

    "},{"location":"zkbnb/core-concept/overview/","title":"Overview - zkBNB Core Concepts","text":""},{"location":"zkbnb/core-concept/overview/#key-features","title":"Key Features","text":""},{"location":"zkbnb/core-concept/overview/#digital-asset-management","title":"Digital Asset Management","text":"

    The zkBNB will serve as an alternative marketplace for issuing, using, paying and exchanging digital assets in a decentralized manner. zkBNB and BSC share the same token universe for BNB, BEP2 and NFT tokens. This defines: - The same token can circulate on both networks, and flow between them bi-directionally via L1 <> L2 communication. - The total circulation of the same token should be managed across the two networks, i.e. the total effective supply of a token should be the sum of the token\u2019s total effective supply on both BSC and BC. - The tokens can only be initially created on BSC in BEP20, then pegged to the zkBNB. It is permissionless to peg token onto zkBNB.

    User can deposit, transfer, and withdraw both non-fungible token and fungible token on zkBNB.

    Users enter the zk-rollup by depositing tokens in the rollup\u2019s contract deployed on the BSC. The zkBNB monitor will track deposits and submit it as a layer2 transaction, once committer verifies the transaction, users get funds on their account, they can start transacting by sending transactions to the committer for processing.

    User can transfer any amount of funds to any existed accounts on zkBNB by sending a signed transaction to the network.

    Withdrawing from zkBNB to BSC is straightforward. The user initiates the withdrawal transaction, the fund will be burned on zkBNB. Once the transaction in the next batch been rolluped, a related amount of token will be unlocked from rollup contract to target account.

    "},{"location":"zkbnb/core-concept/overview/#nft-management-and-marketplace","title":"NFT Management and Marketplace","text":"

    We target to provide an opensource NFT marketplace for users to browse, buy, sell or create their own NFT. The meta-data of NFT on zkBNB sticks to the BSC standard. The ERC721 standard NFT can be seamlessly deposited on zkBNB, or in reverse.

    Above diagram shows the framework of Nft Marketplace and zkBNB. All the buy/sell offer, meta-data of NFT/Collection, medium resources, account profiles are store in the backend of NFT marketplace, only the contendHash, ownership, creatorTreasuryRate and few other fields are recorded on zkBNB. To encourage price discovery, anyone can place buy/sell offer in the marketplace without paying any fees since the offer is cached in the backend instead of being sent to the zkBNB. Once the offer is matched, an AtomicMatch transaction that consist of buy and sell offer will be sent to zkBNB to make the trade happen. Users can also cancel an offer manually by sending a cancel offer transaction to disable the backend cached offer.

    "},{"location":"zkbnb/core-concept/overview/#seamless-l1-wallet-management","title":"Seamless L1 Wallet Management","text":"

    zkBNB natively supports ECDSA signatures and follows EIP712 signing structure, which means most of the Ethereum wallets can seamless support zkBNB. There is no extra effort for BSC users to leverage zkBNB.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/","title":"zkBNB Architecture - zkBNB","text":""},{"location":"zkbnb/core-concept/zkbnb-arch/#zkbnb-architecture","title":"zkBNB Architecture","text":"

    zkBNB is a zero-knowledge scalability solution, or L2, which focuses on straightforward token operations and built-in marketplaces for Gaming and Social use cases. It serves as a scalability solution for the BNB Smart Chain by bundling multiple transactions into a single transaction, reducing costs for on-chain transactions. The Zero Knowledge proof system used in zkBNB ensures a much faster finality time of the L2 transactions, that helps improve the user experience. zkBNB is essentially built on the zk-Rollup architecture.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#zk-rollup-architecture","title":"zk-Rollup Architecture","text":""},{"location":"zkbnb/core-concept/zkbnb-arch/#maximum-throughput","title":"Maximum throughput","text":"

    Pending benchmark\u2026

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#data-availability","title":"Data Availability","text":"

    zkBNB publish state data for every transaction processed off-chain to BSC. With this data, it is possible for individuals or businesses to reproduce the rollup\u2019s state and validate the chain themselves. BSC makes this data available to all participants of the network as calldata.

    zkBNB don\u2019t need to publish much transaction data on-chain because validity proofs already verify the authenticity of state transitions. Nevertheless, storing data on-chain is still important because it allows permissionless, independent verification of the L2 chain\u2019s state which in turn allows anyone to submit batches of transactions, preventing malicious committer from censoring or freezing the chain.

    zkBNB will provide a default client to replay all state on Layer2 based on these call data.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#transaction-finality","title":"Transaction Finality","text":"

    BSC acts as a settlement layer for zkBNB: L2 transactions are finalized only if the L1 contract accepts the validity proof and execute the txs. This eliminates the risk of malicious operators corrupting the chain (e.g., stealing rollup funds) since every transaction must be approved on Mainnet. Also, BSC guarantees that user operations cannot be reversed once finalized on L1.

    zkBNB provides relative fast finality speed within 10 minutes.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#instant-confirmation-zkbs","title":"Instant confirmation ZkBS","text":"

    Even though time to finality is about 10 minutes, it does not affect the usability of the network. The state transition happens immediately once the block been proposed on zkBNB. The rollup operations are totally transparent to most users, users can make further transfers without waiting.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#censorship-resistance","title":"Censorship resistance","text":"

    Committer will execute transactions, produce batches. While this ensures efficiency, it increases the risk of censorship :malicious zk-rollup committer can censor users by refusing to include their transactions in batches.

    As a security measure, zkBNB allow users to submit transactions directly to the rollup contract on Mainnet if they think they are being censored by the operator. This allows users to force an exit from the zk-rollup to BSC without having to rely on the commiter\u2019s permission.

    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"BNB Chain","text":""},{"location":"#bnb-chain-empowering-the-future-of-decentralized-applications","title":"BNB Chain: Empowering the Future of Decentralized Applications","text":"

    BNB Chain is a leading blockchain ecosystem designed to support the growing demands of the decentralized web (Web3). Offering a unique combination of speed, scalability, and affordability, BNB Chain has become a popular choice for developers building decentralized applications (DApps) and for users seeking to participate in the world of decentralized finance (DeFi).

    "},{"location":"#key-features-and-benefits","title":"Key Features and Benefits","text":""},{"location":"#chains","title":"Chains","text":"

    BNB Chain is composed of three blockchains - BNB Smart Chain (BSC), opBNB and BNB Greenfield. Powering and coordinating the ecosystem is the BNB token. Along with fueling transactions on BNB Chain, the BNB token also acts as a governance token. Within this ecosystem, the ownership, usage, and monetization of data are possible for all users and participants in the BNB Chain ecosystem.

    BNB Smart Chain (BSC)

    BNB Smart Chain (BSC) is a high-performance blockchain platform designed to enable the development of scalable and user-friendly decentralized applications (DApps). As a core component of the BNB Chain ecosystem, BSC offers a robust infrastructure for building a wide range of applications, particularly in the decentralized finance (DeFi) space.

    opBNB

    A layer-2 scaling solution for BNB Smart Chain that significantly increases transaction speed and reduces fees. It achieves this by leveraging Optimistic Rollups technology, making BNB Chain even more suitable for high-throughput applications.

    BNB Greenfield

    A decentralized storage infrastructure designed to provide a secure and scalable platform for storing and managing data on the blockchain. It enables users to store files, NFTs, and other digital assets in a decentralized manner, promoting data ownership and control.

    Join BNB Ecosystem

    Share your project with BNB Chain Ecosystem or seeking for cooperations. We want to make it as easy as possible for prjects to get more exposure in BNB Chain Ecosystem or ask for support from the team.

    "},{"location":"#use-cases","title":"Use Cases","text":""},{"location":"#quick-start","title":"Quick Start","text":"BNB Smart Chain

    Getting Started with high performance Layer1 particularly for decentralized finance (DeFi)

    opBNB

    Getting Started with Layer2 scaling solution on BNB Chain ecosystem

    BNB Greenfield

    Getting Started with cutting-edge decentralized storage

    "},{"location":"announce/","title":"Announcements","text":""},{"location":"announce/#announcement","title":"Announcement","text":"Greenfield Mongolian Hardfork (Testnet) Bugfixing on Greenfield Testnet 2024 July 31 Greenfield Mongolian Hardfork (Mainnet) Bugfixing on Greenfield Mainnet 2024 August 8"},{"location":"announce/feynman-bsc/","title":"Feynman Hardfork(BSC)","text":""},{"location":"announce/feynman-bsc/#feynman-upgrade-of-bsc","title":"Feynman Upgrade of BSC","text":"Hardfork"},{"location":"announce/feynman-bsc/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Haber upgrade will happen at:

    "},{"location":"announce/feynman-bsc/#upgrade-to-bsc-node-v1313-before-hardfork","title":"Upgrade to BSC Node v1.3.13 Before Hardfork","text":"

    Feyman upgrade is the most important milestone of BNB Chain Fusion. The BNB Chain Fusion is a strategic shift to migrate the Beacon Chain\u2019s functionalities to BNB Smart Chain (BSC) and retire Beacon Chain. This move aims to streamline the network, improve efficiency, reduce security risks, and align BNB Chain\u2019s architecture with the current technological demands and future growth. BEP333 propose to securely and smoothly transit the BNB Beacon Chain and BNB Smart Chain (BSC) from a dual-chain structure into a single chain structure and thus decommission the Beacon Chain.

    Due to Feyman\u2019s upgrade, it will have a significant impact on the BNB ecosystem. We welcome the community to submit issues on GitHub or Discord. Kindly remind that BNB Chain has a bug bounty program if anyone find any security issues.

    "},{"location":"announce/feynman-bsc/#key-highlight","title":"Key Highlight","text":"

    BEP-294, BEP-297 and BEP-299 will be deployed in the BSC Feynman hard fork.

    "},{"location":"announce/final-sunset-bc-testnet/","title":"Final Sunset Hardfork(BC testnet)","text":""},{"location":"announce/final-sunset-bc-testnet/#final-sunset-hardfork-of-bc-testnet","title":"Final Sunset Hardfork of BC Testnet","text":"Hardfork"},{"location":"announce/final-sunset-bc-testnet/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Final Sunset Hardfork will happen at:

    "},{"location":"announce/final-sunset-bc-testnet/#upgrade-to-bc-node-v01023-before-hardfork","title":"Upgrade to BC Node v0.10.23 Before Hardfork","text":"

    BC node need to be upgraded before the hardfork time.

    "},{"location":"announce/final-sunset-bc-testnet/#upgrade-instructions","title":"Upgrade Instructions","text":"

    As a fullnode runner, you need to take the following steps before the hardfork block height.

    1) Download the new v0.10.23 binary and replace the previous version.

    2) Download the new config file app.toml to replace the previous version or add the following under the [upgrade] module of app.toml.

    FinalSunsetHeight = 56218686\n

    3) Stop the bnbchaind process and restart it with v0.10.23.

    service bnbchaind restart\n
    "},{"location":"announce/final-sunset-bc-testnet/#key-highlight","title":"Key Highlight","text":"

    After Final Sunset, the cross-chain communication between the Beacon Chain and BSC will be completely stopped. The validators in the Beacon Chain community will gradually shut down, and the entire chain will no longer accept new transactions or propose new blocks. For more information about BNB Chain Fusion, please refer to this.

    "},{"location":"announce/haber-bsc/","title":"Haber Hardfork(BSC)","text":""},{"location":"announce/haber-bsc/#haber-upgrade-of-bsc","title":"Haber Upgrade of BSC","text":"Hardfork"},{"location":"announce/haber-bsc/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Haber upgrade will happen at:

    "},{"location":"announce/haber-bsc/#upgrade-to-bsc-node-v148-before-hardfork","title":"Upgrade to BSC Node v1.4.8 Before Hardfork","text":"

    Release v1.4.8 is a cut-in hard fork release for BSC Testnet and Mainnet, the HF name is: Haber, it only supports one BEP: BEP-381: Precompile for secp256r1 Curve Support

    "},{"location":"announce/haber-bsc/#key-highlight-eip-7212-secp256r1-curve-precompile","title":"Key Highlight: EIP 7212 - secp256r1 Curve Precompile","text":"

    BSC would use address 0x100 as secp256r1 pre-compile contract, which is same as other major chains to make it easier for developers. Developers may refer this code on how to use this pre-compile contract: https://github.com/getclave/clave-contracts/blob/master/contracts/helpers/VerifierCaller.sol , which is same as other major chains to make it easier for developers.

    "},{"location":"announce/haber-bsc/#key-highlight-bep-336-enable-blob-carrying-transaction-for-bsc","title":"Key Highlight: BEP 336 - Enable Blob Carrying Transaction for BSC","text":"

    Introduce a new transaction format for \u201cblob-carrying transactions\u201d which contain a large amount of data that cannot be accessed by EVM execution, but whose commitment can be accessed. The format is intended to be fully compatible with the format that will be used in full sharding.

    "},{"location":"announce/haber-opbnb/","title":"Haber Hardfork(opBNB)","text":""},{"location":"announce/haber-opbnb/#haber-upgrade-of-opbnb","title":"Haber Upgrade of opBNB","text":"Hardfork"},{"location":"announce/haber-opbnb/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Haber upgrade will happen at:

    "},{"location":"announce/haber-opbnb/#upgrade-to-opbnb-node-v042-before-hardfork","title":"Upgrade to opBNB Node v0.4.2 Before Hardfork","text":"

    op-node and op-geth need to be upgraded before the hardfork time.

    "},{"location":"announce/haber-opbnb/#key-highlight-eip-7212-secp256r1-curve-precompile","title":"Key Highlight: EIP 7212 - secp256r1 Curve Precompile","text":"

    One of the significant enhancements in this release is the introduction of a precompile for the secp256r1 curve, as specified in EIP 7212. This precompile allows for efficient elliptic curve operations, which is crucial for improving the performance and security of cryptographic applications on the blockchain.

    "},{"location":"announce/haber-opbnb/#key-highlight-bep-336-switch-da-from-calldata-to-blob-of-bsc","title":"Key Highlight: BEP 336 - Switch DA from calldata to blob of BSC","text":"

    DA data will be submitted to the BSC network in blob format. Regular BSC nodes only retain blob data from the past 18 days. If you are syncing data from the genesis block or are more than 18 days behind the latest block, you will need to ensure that your configured L1 endpoint supports persisting blob data for a longer period of time. We will ensure that the Testnet snapshot provided by this snapshot repository is within the 18-day range, so you can also choose to use the snapshot to avoid relying on older blob data to start your new node.

    "},{"location":"announce/mongolian-greenfield/","title":"Mongolian Hardfork(Greenfield)","text":""},{"location":"announce/mongolian-greenfield/#mongolian-upgrade-of-greenfield","title":"Mongolian Upgrade of Greenfield","text":"Hardfork"},{"location":"announce/mongolian-greenfield/#upgrade-timeline","title":"Upgrade Timeline","text":""},{"location":"announce/mongolian-greenfield/#validators-and-sps-should-complete-upgrading-to-the-latest-version-before-hardfork","title":"Validators and SPs should complete upgrading to the latest version before hardfork:","text":"

    For Validators: greenfield v1.9.0

    For SPs: greenfield-storage-provider v1.9.0

    "},{"location":"announce/mongolian-greenfield/#new-features-introduced","title":"New features introduced:","text":""},{"location":"announce/mongolian-greenfield/#bug-fixing","title":"Bug fixing","text":""},{"location":"announce/mongolian-greenfield/#docs","title":"Docs","text":""},{"location":"announce/second-sunset-bc-testnet/","title":"Second Sunset Hardfork(BC testnet)","text":""},{"location":"announce/second-sunset-bc-testnet/#second-sunset-hardfork-of-bc-testnet","title":"Second Sunset Hardfork of BC Testnet","text":"Hardfork"},{"location":"announce/second-sunset-bc-testnet/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Second Sunset Hardfork will happen at:

    "},{"location":"announce/second-sunset-bc-testnet/#upgrade-to-bc-node-v01021-before-hardfork","title":"Upgrade to BC Node v0.10.21 Before Hardfork","text":"

    BC node need to be upgraded before the hardfork time.

    "},{"location":"announce/second-sunset-bc-testnet/#upgrade-instructions","title":"Upgrade Instructions","text":"

    As a fullnode runner, you need to take the following steps before the hardfork block height.

    1) Download the new v0.10.21 binary and replace the previous version.

    2) Download the new config file app.toml to replace the previous version or add the following under the [upgrade] module of app.toml.

    SecondSunsetHeight = 54554742\n

    3) Stop the bnbchaind process and restart it with v0.10.21.

    service bnbchaind restart\n
    "},{"location":"announce/second-sunset-bc-testnet/#key-highlight","title":"Key Highlight","text":"

    All TimeLocks and AtomicSwaps on BC tesnet will automatically be refunded to user accounts. All the BSC delegations will be automatically undelegated and refunded to user accounts after the unbonding period. For more information about BNB Chain Fusion, please refer to this.

    "},{"location":"announce/second-sunset-bc/","title":"Second Sunset Hardfork(BC)","text":""},{"location":"announce/second-sunset-bc/#second-sunset-hardfork-of-bc","title":"Second Sunset Hardfork of BC","text":"Hardfork"},{"location":"announce/second-sunset-bc/#upgrade-timeline","title":"Upgrade Timeline","text":"

    The Second Sunset Hardfork will happen at:

    "},{"location":"announce/second-sunset-bc/#upgrade-to-bc-node-v01022-before-hardfork","title":"Upgrade to BC Node v0.10.22 Before Hardfork","text":"

    BC node need to be upgraded before the hardfork time.

    "},{"location":"announce/second-sunset-bc/#upgrade-instructions","title":"Upgrade Instructions","text":"

    As a fullnode runner, you need to take the following steps before the hardfork block height.

    1) Download the new v0.10.22 binary and replace the previous version.

    2) Download the new config file app.toml to replace the previous version or add the following under the [upgrade] module of app.toml.

    SecondSunsetHeight = 378062790\n

    3) Stop the bnbchaind process and restart it with v0.10.22.

    service bnbchaind restart\n
    "},{"location":"announce/second-sunset-bc/#key-highlight","title":"Key Highlight","text":"

    All TimeLocks and AtomicSwaps on BC tesnet will automatically be refunded to user accounts. All the BSC delegations will be automatically undelegated and refunded to user accounts after the unbonding period. For more information about BNB Chain Fusion, please refer to this.

    "},{"location":"announce/veld-greenfield/","title":"Veld Hardfork(Greenfield)","text":""},{"location":"announce/veld-greenfield/#veld-upgrade-of-greenfield","title":"Veld Upgrade of Greenfield","text":"Hardfork"},{"location":"announce/veld-greenfield/#upgrade-timeline","title":"Upgrade Timeline","text":""},{"location":"announce/veld-greenfield/#validators-and-sps-should-complete-upgrading-to-the-latest-version-before-hardfork","title":"Validators and SPs should complete upgrading to the latest version before hardfork:","text":"

    For Validators: greenfield v1.8.0

    For SPs: greenfield-storage-provider v1.8.0

    "},{"location":"announce/veld-greenfield/#new-features-introduced","title":"New features introduced:","text":"

    No new feature is introduced.

    "},{"location":"announce/veld-greenfield/#bug-fixing","title":"Bug fixing","text":""},{"location":"bc-fusion/","title":"BNB Chain Fusion","text":"BNB Chain Fusion

    The BNB Chain Fusion is a strategic shift to migrate the BNB Beacon Chain\u2019s functionalities to BNB Smart Chain (BSC) and retire BNB Beacon Chain. This move aims to streamline the network, improve efficiency, reduce security risks, and align BNB Chain's architecture with the current technological demands and future growth.

    Roadmap

    The detailed roadmap of BNB Chain fusion.

    Stake Migration

    Migrate staking from the Beacon Chain to BSC for higher APY.

    Token Migration

    Transfer token from Beacon Chain to BSC with single click.

    Token Bind

    Bind the token between BC and BSC to enable bridge, and token recover even after the sunset of Beacon Chain.

    Participate Staking

    Stake on BSC directly to secure the network and earn BNB!

    Participate Governance

    Participate in governance on the BSC through Tally

    "},{"location":"bc-fusion/overview/","title":"Overview - BC Fusion","text":""},{"location":"bc-fusion/overview/#overview","title":"Overview","text":"

    BNB Beacon Chain is a blockchain developed by the BNB Chain community that implements a vision of a decentralized exchange (DEX) for digital assets. Besides this, Beacon Chain and BSC is a dual-chain structure: Beacon Chain helps to enhance the security of BSC as a staking and governance layer. With the rise of various other forms of Dex, order-book based decentralized exchange was decommissioned in BEP151. With the quick evolution of BSC, the Beacon Chain has become a burden. The cross-chain bridge that connects the two chains slows down the development iteration and always exposes BNB to a certain level of security vulnerabilities. It\u2019s time to take a step further and migrate the functionality of Beacon Chain to BSC, allowing Beacon Chain to retire.

    There will be several pahses to retrie Beacon Chain:

    All stakholders (e.g., token holders/owners, validators, project owners) should pay attention BNB Chain blog for releated annonuncements and take actions proactively.

    For more information about BNB Chain fusion, please refer to BEP-333.

    For the roadmap and milestons of BNB Chain fusion, please refer to the blog.

    "},{"location":"bc-fusion/developers/crosschain-redelegation/","title":"Cross Chain Redelegation","text":""},{"location":"bc-fusion/developers/crosschain-redelegation/#crosschain-redelgation","title":"Crosschain Redelgation","text":"

    To migrate the exisiting delegation from BNB Beacon chain (the old BSC staking) to the new BNB smart chain native staking, crosschain redelegation can be used. A user can submit a message called MsgSideChainStakeMigration to the Beacon chain. Underlying, it will unbound the delegation immediately on BC (without wating unbond period), sends a cross-chain transaction to BSC to delegate to a native BSC validator.

    The definition of MsgSideChainStakeMigration is as the blow.

    type MsgSideChainStakeMigration struct {\n    ValidatorSrcAddr sdk.ValAddress        `json:\"validator_src_addr\"`\n    ValidatorDstAddr sdk.SmartChainAddress `json:\"validator_dst_addr\"`\n    DelegatorAddr    sdk.SmartChainAddress `json:\"delegator_addr\"`\n    RefundAddr       sdk.AccAddress        `json:\"refund_addr\"`\n    Amount           sdk.Coin              `json:\"amount\"`\n}\n

    Be noted: please make sure input the DelegatorAddr correctly, otherwise you will lose the fund permanently.

    For more details, please refer to the codes: https://github.com/bnb-chain/bnc-cosmos-sdk/blob/bc-fusion/x/stake/types/stake_migration.go#L29

    "},{"location":"bc-fusion/developers/gov/","title":"New Governance","text":""},{"location":"bc-fusion/developers/gov/#governance","title":"Governance","text":"

    This guide provides an overview of the key operations of governance, including creating proposals, casting votes, and executing proposals. For the general introduction of governance, please refer to Governance Mechanism.

    "},{"location":"bc-fusion/developers/gov/#contract","title":"Contract","text":"

    The BSC governance facilitates decentralized decision-making within the BSC ecosystem, utilizing two primary smart contracts: GovToken for governance token management and Governor for proposal management and voting.

    "},{"location":"bc-fusion/developers/gov/#create-proposal","title":"Create Proposal","text":"

    To create a proposal, you need to call the propose function of Governor with the following parameters:

    function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory\n    description) public returns (uint256 proposalId)\n
    "},{"location":"bc-fusion/developers/gov/#cast-vote","title":"Cast Vote","text":"

    To cast a vote, you need to call the castVote function of Governor with the following parameters:

    function castVote(uint256 proposalId, uint8 support, string memory reason) public returns (uint256)\n
    "},{"location":"bc-fusion/developers/gov/#check-proposal-state","title":"Check Proposal State","text":"

    To get the state of a proposal, you need to call the state function of Governor with the following parameters:

    function state(uint256 proposalId) public view returns (ProposalState)\n
    "},{"location":"bc-fusion/developers/gov/#queue-proposal","title":"Queue Proposal","text":"

    To schedules the proposal for execution, you need to call the queue function of Governor with the following parameters:

    function queue(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)\npublic returns (uint256 proposalId)\n
    "},{"location":"bc-fusion/developers/gov/#execute-proposal","title":"Execute Proposal","text":"

    To apply the changes after the timelock delay, you need to call the execute function of Governor with the following parameters:

    function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)\npublic payable returns (uint256)\n
    "},{"location":"bc-fusion/developers/gov/#delegate-vote","title":"Delegate Vote","text":"

    To delegate voting power to someoneles, you need to call the delegateVote function of GovToken with the following parameters:

    function delegateVote(address delegator, address delegatee) external\n
    "},{"location":"bc-fusion/developers/gov/#contract-abi","title":"Contract ABI","text":"

    For the full interfaces of Governor, please refer to the ABI file.

    For the full interfaces of GovToken, please refer to the ABI file.

    "},{"location":"bc-fusion/developers/staking/","title":"New Staking","text":""},{"location":"bc-fusion/developers/staking/#staking","title":"Staking","text":"

    This guide provides an overview of the key operations of staking, including creating validators, editing validator information, and performing delegation operations. For the general introduction of staking, please refer to Staking Mechanism.

    "},{"location":"bc-fusion/developers/staking/#contract","title":"Contract","text":"

    The BSC staking mainly uses the smart contracts StakeHub for validator management and delegation management.

    "},{"location":"bc-fusion/developers/staking/#creating-a-validator","title":"Creating a Validator","text":"

    To create a validator, use the createValidator function with the following parameters:

      function createValidator(\n    address consensusAddress,\n    bytes calldata voteAddress,\n    bytes calldata blsProof,\n    Commission calldata commission,\n    Description calldata description\n) external payable\n

    Note: Creating a validator requires locking 1 BNB, and the transaction must be sent with a sufficient BNB amount to cover this lock amount plus any self-delegation, in total 2001BNB.

    "},{"location":"bc-fusion/developers/staking/#editing-validator-information","title":"Editing Validator Information","text":""},{"location":"bc-fusion/developers/staking/#edit-consensus-address","title":"Edit Consensus Address","text":"

    To change the consensus address of a validator, use the editConsensusAddress function with the following paramters:

    function editConsensusAddress(address newConsensusAddress) external\n
    "},{"location":"bc-fusion/developers/staking/#edit-commission-rate","title":"Edit Commission Rate","text":"

    To update the commission rate of a validator, use the editCommissionRate function with the following paramters:

    function editCommissionRate(uint64 newCommissionRate) external\n
    "},{"location":"bc-fusion/developers/staking/#edit-description","title":"Edit Description","text":"

    To update the description of a validator, use the editDescription function with the following parameters:

    function editDescription(Description memory newDescription) external\n
    "},{"location":"bc-fusion/developers/staking/#edit-vote-address","title":"Edit Vote Address","text":"

    To change the vote address of a validator, use the editVoteAddress function with the following parameters:

    function editVoteAddress(bytes calldata newVoteAddress, bytes calldata blsProof) external\n
    "},{"location":"bc-fusion/developers/staking/#delegation-operations","title":"Delegation Operations","text":""},{"location":"bc-fusion/developers/staking/#delegate","title":"Delegate","text":"

    To delegate BNB to a validator, call the delegate function with the following parameters:

    function delegate(address operatorAddress, bool delegateVotePower) external payable\n
    "},{"location":"bc-fusion/developers/staking/#undelegate","title":"Undelegate","text":"

    To undelegate BNB from a validator, use the undelegate function with the following parameters:

    function undelegate(address operatorAddress, uint256 shares) external\n
    "},{"location":"bc-fusion/developers/staking/#redelegate","title":"Redelegate","text":"

    To redelegate BNB from one validator to another, use the redelegate function with the following parameters:

    function redelegate(address srcValidator, address dstValidator, uint256 shares, bool delegateVotePower) external\n
    "},{"location":"bc-fusion/developers/staking/#claim","title":"Claim","text":"

    To claim undelegated BNB after the unbonding period, use the claim function for a single request or claimBatch for multiple requests:

    function claim(address operatorAddress, uint256 requestNumber) external\n
    function claimBatch(address[] calldata operatorAddresses, uint256[] calldata requestNumbers) external\n
    "},{"location":"bc-fusion/developers/staking/#faqs","title":"FAQs","text":""},{"location":"bc-fusion/developers/staking/#what-are-the-functionsinterfaces-of-each-validators-credit-contract","title":"What are the functions/interfaces of each validator\u2019s credit contract?","text":"

    For each validator, there is a credit contract which will be automatically deployed when it is created. Meanwhile, the conctract cannot be upgraded or changed by any validator operator.

    The credit contract is a BEP20 contract, and the ABI is the same as Stake Credit contract.

    It provides functions for querying delegations, including:

    "},{"location":"bc-fusion/developers/staking/#how-to-get-the-sharesbnb-amount-for-a-delegator","title":"How to get the shares/BNB amount for a delegator?","text":"

    For any specific validator, please call the balanceOf function of the validator\u2019s creat contract to get the delegator\u2019s shares. To get the BNB amount instead of shares, the function getPooledBNB can be used.

    To get the shares of all validators, please call the balanceOf function for each valiator and sum up the results. Please refer to the following to see how to get the information of all validators, and use a muticall contract to improve the efficiency.

    "},{"location":"bc-fusion/developers/staking/#how-to-calculte-the-bnb-amount-for-a-specific-amount-of-shares","title":"How to calculte the BNB amount for a specific amount of shares?","text":"

    The credit contract provides the getPooledBNBByShares function to calculate the BNB amount for some specific amount of shares.

    To do the vice visa, please use the getSharesByPooledBNB function to calculate the shares for some specific BNB amount.

    "},{"location":"bc-fusion/developers/staking/#how-to-calculate-the-aprapy-of-a-validator","title":"How to calculate the APR/APY of a validator?","text":"

    Please be noted that each validator will have its own APR/APY, and the staking system will auto compound the rewards.

    The reward is distributed to each validator\u2019s BNB pool at 00:00:00 UTC time every day. To calculate the APR/APY of a validator, the total pooled BNB amount and the corresponding reward amount for the same day are needed.

    The StakeHub contract provides the getValidatorTotalPooledBNBRecord(address,uint256)(uint256) and getValidatorRewardRecord(address,uint256)(uint256) for the purpose.

    The following codes show how to calculate the APY at a given day:

    // example code, do not use it in production\n\n// stakehub is the instance of StakeHub contract\nstakeHub, _ := contracts.NewStakeHub(ethcommon.HexToAddress(\"0x0000000000000000000000000000000000002002\"), client.GetEthClient())\n\n// get how many blocks are in a day\ninterval, _ := stakeHub.BREATHEBLOCKINTERVAL(nil)\n\n// get the block time of a given block\nheader, _ := p.client.GetBlockHeader(blockHeight)\n\n// calculate the index paramter to call the following functions\nindex := int64(header.Time) / interval.Int64()\n\n// get the total pooled BNB amount and the corresponding reward amount for the given validator and index\ntotalPooledBNB, _ := stakeHub.GetValidatorTotalPooledBNBRecord(nil, validatorOperatorAddress, index)\nreward, _ := stakeHub.GetValidatorRewardRecord(nil, validatorOperatorAddress, index)\n\n// calculate the APY\nrate, _ := big.NewFloat(0).Quo(big.NewFloat(0).SetInt(reward), big.NewFloat(0).SetInt(totalPooledBNB)).Float64()\napy := math.Pow(1+rate, 365) - 1.0\n
    "},{"location":"bc-fusion/developers/staking/#how-to-get-the-unbonding-delegations-of-a-delegator-and-hisher-unbonding-requests-which-can-be-claimed","title":"How to get the unbonding delegations of a delegator, and his/her unbonding requests which can be claimed?","text":"

    The credit contract provides the pendingUnbondRequest function to get the unbonding delegation count for a delegator. To review the details of a unbond request, please call the unbondRequest function with a index parameter to define which unbond request will be returned.

    To get the claimable unbonding requests, please call the claimableUnbondRequest function to get the count of claimable ones.

    To get the locked BNBs for unbonding requests, please use the lockedBNBs function. It has the parameter number to define the sum of first number unbonding requests\u2019 BNB locked in the delegator\u2019s unbond queue. Set the number to 0 to get all the locked BNBs.

    "},{"location":"bc-fusion/developers/staking/#how-to-get-the-reward-of-a-delegator","title":"How to get the reward of a delegator?","text":"

    The contracts does not save the initial delegation amount of a delegator. To get the accumulated reward, the following steps can be taken: 1) track the initial delegation amount in your system, 2) call the getPooledBNB of the credit contract of a validator, 3) do the math.

    "},{"location":"bc-fusion/developers/staking/#how-to-get-the-total-staking-address-of-a-validator","title":"How to get the total staking address of a validator?","text":"

    The contract does not provide a function to get the total staking address of a validator. It needs a offchain service to index Delegated, Redelegated, Undelegated events for the purpose. For example, you can consider building an indexer to crawl Delegated, Redelegated, Undelegated events on stakeHub contract first. Then sort the events according to your requirements.

    "},{"location":"bc-fusion/developers/staking/#how-to-get-all-validators-information","title":"How to get all validators\u2019 information?","text":"

    The StakeHub contract provides the getValidators function to get all validators\u2019 information, including the operator addresses and credit contract addresses.

    To get more information of a specific validator, please refer to the following functions:

    "},{"location":"bc-fusion/developers/staking/#contract-abi","title":"Contract ABI","text":"

    For the full interfaces of StakeHub, please refer to the ABI file.

    "},{"location":"bc-fusion/developers/system-contracts/","title":"Build-in System Contracts","text":""},{"location":"bc-fusion/developers/system-contracts/#build-in-system-contracts","title":"Build-in System Contracts","text":"

    GitHub Implementation link: https://github.com/bnb-chain/bsc-genesis-contract

    Contract Name Contract Address ABI File Stake Hub Contract 0x0000000000000000000000000000000000002002 stakehub Stake Credit Contract 0x0000000000000000000000000000000000002003 stakecredit Governor Contract 0x0000000000000000000000000000000000002004 bscgovernor Gov Token Contract 0x0000000000000000000000000000000000002005 govtoken Timelock Contract 0x0000000000000000000000000000000000002006 bsctimelock Token Recover Portal Contract 0x0000000000000000000000000000000000003000 tokenrecoverportal"},{"location":"bc-fusion/developers/system-contracts/#precompiled-contracts","title":"Precompiled Contracts","text":""},{"location":"bc-fusion/developers/system-contracts/#secp256k1-signature-recover","title":"Secp256k1 Signature Recover","text":"

    The precompiled contract is used to verify the signature of a message signed using the secp256k1 elliptic curve cryptography algorithm. It will also retrun the Tendermint address of the signer.

    "},{"location":"bc-fusion/developers/system-contracts/#verify-double-sign-evidence","title":"Verify Double Sign Evidence","text":"

    The precompiled contract is used to verify the submitted double sign evidence, which includes the two block headers signed by the same validator at different times.

    "},{"location":"bc-fusion/developers/system-contracts/#build-in-system-contracts_1","title":"Build-in System Contracts","text":""},{"location":"bc-fusion/developers/system-contracts/#stake-hub-contract","title":"Stake Hub Contract","text":"

    The Stake Hub contract is a contract that manages the staking process, including delegation, undelegation, redelegation, and claiming rewards.

    "},{"location":"bc-fusion/developers/system-contracts/#stake-credit-contract","title":"Stake Credit Contract","text":"

    The Stake Credit contract is a template proxy contract. When a validator is created, a new stake credit contract is deployed, to manage staking credit and facilitate the exchange between credit and BNB.

    "},{"location":"bc-fusion/developers/system-contracts/#governor-contract","title":"Governor Contract","text":"

    The Governor contract is a contract that manages the BNB Smart Chain governance process. It allows users to propose and vote on changes to the protocol.

    "},{"location":"bc-fusion/developers/system-contracts/#gov-token-contract","title":"Gov Token Contract","text":"

    The Gov Token contract is a contract that manages the governance token, i.e., govBNB.

    "},{"location":"bc-fusion/developers/system-contracts/#timelock-contract","title":"Timelock Contract","text":"

    The Timelock contract is a contract that allows executing a time lock on some specific operations (e.g., token recovery). After the timelock period, the locked tokens can be claimed or released.

    "},{"location":"bc-fusion/developers/system-contracts/#token-recover-portal-contract","title":"Token Recover Portal Contract","text":"

    The Token Recover Portal contract is a contract that allows users to recover their BEP2/BEP8 tokens, which must have been bound to BEP20 tokens, after the shutdown of the cross-chaind transfer between BNB Smart Chain and BNB Beacon Chain.

    "},{"location":"bc-fusion/owners/bind/","title":"Bind Your Tokens","text":""},{"location":"bc-fusion/owners/bind/#token-bind","title":"Token Bind","text":"

    Token binding was introduced to faciliate that one token can circulate in both BC and BSC with confirmed total supply.

    NOTE: The BC Fusion program is scheduled for implementation in April 2024. Please ensure careful planning for the asset migration and keep the fund safe.

    Please check the tutorial Confirm if the Assets Support Cross-chain Transfers to verify if the token allows cross-chain transfers. If the answer is positive, congratulations! You don\u2019t need to do anything. Otherwise, it is highly recommended to follow the Token Bind Tool to deploy a BEP20 token on BSC and enable cross-chain functionality.

    Due to the time limitation, the Token Issuer should take actions as soon as possbile. It is recommended that the Token Issuer use multiple channels to promptly notify asset holders to migrate as soon as possible.

    Note: BEP2/BEP8 assets that do not support cross-chain functionality will be permanently lost after BC Fusion. Users will be unable to recover these assets forever.

    "},{"location":"bc-fusion/owners/liquidity-check/","title":"Cross Chain Liquidity Check and Repair","text":""},{"location":"bc-fusion/owners/liquidity-check/#cross-chain-liquidity-check-and-repair","title":"Cross-Chain Liquidity Check and Repair","text":"

    After token binding, tokens can be seamlessly transferred between BC and BSC. However, some improper operations may lead to eventual cross-chain transfer failures. For example, performing a mint operation on one chain but not on the other can result in different supplies on the two chains, making it impossible to transfer all assets from the chain with the larger total supply to the other chain. This doc will introduce the token circulation model of BNB Chain and how to repair cross-chain liquidity issues. We urge all token issuers to complete liquidity checks and repairs before BC Fusion, although this article remains valid after BC Fusion.

    "},{"location":"bc-fusion/owners/liquidity-check/#circulation-model","title":"Circulation Model","text":"

    The architecture of cross-chain communication is as in the above diagram. The cross-chain transfer is the key communication between the two blockchains. Essentially the logic is:

    1. The transfer-out blockchain will lock the amount from source owner addresses into a system controlled address/contracts
    2. The transfer-in blockchain will unlock the amount from the system controlled address/contracts and send it to target addresses.

    The system controlled vault on BNB Beacon Chain is bnb1v8vkkymvhe2sf7gd2092ujc6hweta38xadu2pj which is generated by code, and the vault on BNB Smart Chain is a system smart contract called Token Hub. The funds on these two addresses are treated as locked which are not part of the circulating supply.

    "},{"location":"bc-fusion/owners/liquidity-check/#liquidity-check-and-repair","title":"Liquidity Check and Repair","text":"

    One of the objectives of BC Fusion is to transfer all tokens from the Beacon Chain to BSC. Therefore, we must ensure that there is sufficient liquidity on BSC, meaning the total amount of tokens locked in BSC\u2019s Tokenhub is greater than the circulating supply on the Beacon Chain.

    Let\u2019s use take DAI token as an example:

    1. Visit the basic information page of DAI on the Beacon Chain explorer to obtain the circulating supply on the Beacon Chain (Csupply) and the contract address on BSC.
    2. Visit the BSC explorer to check the locked amount/liquidity of this token. The URL is https://bscscan.com/token/${BSC_contract_address}?a=0x0000000000000000000000000000000000001004. Replace ${BSC contract address} with the BSC contract address obtained in step 1. And you will see the balance as below:

    Therefore, Tokenhub on BSC still lacks 1,999,973.28 - 1.755760127949865335 = 1,999,971.5242398721 DAI. To avoid issues caused by precision loss, we recommend adding slightly more liquidity than the calculated value. In this case, it would be 1,999,972 DAI. If you find that the amount of locked tokens on BSC is greater than the circulating supply (Csupply) on the Beacon Chain, it means there is sufficient liquidity, and no further action is needed.

    If there is a liquidity shortage, the issuer of the token should transfer the missing liquidity to Tokenhub, for example, 1,999,972 DAI for the DAI token mentioned above. The source of these tokens is up to the issuer to determine: they could be minted or collected from various accounts.

    "},{"location":"bc-fusion/post-fusion/faq/","title":"FAQ","text":""},{"location":"bc-fusion/post-fusion/faq/#faq","title":"FAQ","text":""},{"location":"bc-fusion/post-fusion/faq/#1-what-will-happen-during-and-after-the-final-sunset-hardfork","title":"1. What will happen during and after the final sunset hardfork?","text":"

    Before executing Final Sunset, users still have the opportunity to transfer funds across chains. However, after Final Sunset, cross-chain communication between the Beacon Chain and BSC will be completely stopped.

    After Sunset Fork (i.e., post fusion), the validators in the Beacon Chain community will gradually shut down, and the entire chain will no longer accept new transactions or propose new blocks.

    Some of the funds will be permanently locked:

    All these funds are not recoverable after the Final Sunset Fork.

    After BC shutdown, the core dev team will dump the ledger of Beacon Chain and generate a merkle tree. A governance proposal will be submitted to set the merkel root and approver account of the token migration contract. A dapp (token recovery dApp) will be provided for token migration from Beacon Chain to BSC. All the blockchain data of Beacon Chain will be uploaded to Greenfield, Filecoin and Arweave for archive.

    "},{"location":"bc-fusion/post-fusion/faq/#2what-users-should-do-to-manage-their-bep2bep8-assets-before-and-after-the-fusion","title":"2.What users should do to manage their BEP2/BEP8 assets before and after the fusion?","text":"

    Before the final sunset hardfork:

    After the final sunset hadfork (i.e., post fusion):

    Important: to use the token recovery dApp, the private key/mnemonic for your BC account will be used to prove that you are the owner of the assets. Please take care of your key/mnemonic.

    "},{"location":"bc-fusion/post-fusion/faq/#3-how-do-users-access-the-balance-snapshot-post-fusion","title":"3. How do users access the balance snapshot post fusion?","text":""},{"location":"bc-fusion/post-fusion/faq/#4-can-i-still-acccess-the-bc-releated-services-or-products-after-the-fusion","title":"4. Can I still acccess the BC releated services or products after the fusion?","text":"

    Most of the BC related services and products will be shut down after the final sunset hardfork, inluding and not limited to:

    Be noted: No snapshot will be provided for any of the BC related services and products.

    The Beacon Chain Explorer will keep running for users to query the blockchain data, however, the explorer for BC testnet will be shut down if there is no query traffic for a long time.

    "},{"location":"bc-fusion/post-fusion/merkle-tree-verify/","title":"Merkle Proof Verification","text":""},{"location":"bc-fusion/post-fusion/merkle-tree-verify/#verify-merkle-tree-proofs","title":"Verify Merkle Tree Proofs","text":"

    The BEP299 describes how to recover the bound BEP2/BEP8 on the BSC afer the fusion. One of the most important steps is to generate and verify the Beacon Chain merkle tree proofs. If a wrong merkle tree root is generated, the bound BEP2/BEP8 cannot be recovered and there will a huge financial loss.

    Therefore, the communities are encouraged to use the following tools to verify the proofs and report any issues.

    To do the verification, please follow the detailed steps in the following links:

    "},{"location":"bc-fusion/post-fusion/token-recovery/","title":"Token Recovery","text":""},{"location":"bc-fusion/post-fusion/token-recovery/#token-recovery-dapp","title":"Token Recovery dApp","text":"

    To facilitate the token migration after the Beacon Chain shutdown, the BEP299 is proposed to recover the BEP2/BEP8 assets on the Beacon Chain to the BSC chain. This document will guide you through the process of token recovery.

    Be noted:

    URL:

    "},{"location":"bc-fusion/post-fusion/token-recovery/#steps","title":"Steps","text":""},{"location":"bc-fusion/post-fusion/token-recovery/#step-1-connect-to-your-bc-wallet","title":"Step 1: Connect to your BC wallet.","text":"

    When opening the token recovery dApp, you will be prompted to connect to your wallet.

    BNB Chain Wallet and Trust Wallet will be supported (Trust wallet support will come soon).

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-2-select-the-bep2bep8-assets-to-be-recovered","title":"Step 2: Select the BEP2/BEP8 assets to be recovered.","text":"

    Click the \u201cRecover Now\u201d button to start the recovery process.

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-3-input-the-receiver-address","title":"Step 3: Input the receiver address.","text":"

    The receiver address on BSC is the address where the BEP2/BEP8 assets will be recovered to. The token recovery dApp will try to get the BSC address from your wallet automatically.

    If the address is not populated or you want to use a different address, you can also input the address you want to use.

    Be noted:

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-4-confirm-the-receiver-address-and-signing","title":"Step 4: Confirm the receiver address and signing.","text":"

    By confirming the token recovery request, you will be promoted to sign a message via your wallet.

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-5-send-the-token-recovery-transaction-to-bsc","title":"Step 5: Send the token recovery transaction to BSC.","text":"

    You will be asked to switch to the BSC network in your wallet.

    The connected address should be the receiver address inputted in the previous step. If it is not, the token recovery dApp will detect it and ask you to switch to the correct account in your wallet.

    Then click the \u201cConfirm\u201d button to send the token recovery transaction to BSC.

    You will be prompted to sign and confirm the transaction, which will be sent to the BSC.

    "},{"location":"bc-fusion/post-fusion/token-recovery/#step-6-wait-for-the-recovery","title":"Step 6: Wait for the recovery.","text":"

    After the transaction is sent, the token recovery dApp will populate a window to indicate that the token recovery request is sent successfully.

    Finally, you need to wait for 7 days for the BEP2/BEP8 assets to be recovered on BSC and received in your wallet.

    "},{"location":"bc-fusion/users/assets/","title":"Manage Your Assets","text":""},{"location":"bc-fusion/users/assets/#asset-management","title":"Asset Management","text":"

    The BNB Chain community recently introduced BEP333: BNB Chain Fusion. This BEP aims to retire the BNB Beacon Chain from the BNB Chain ecosystem. The goal is to enhance the development efficiency, security, and asset utilization efficiency of BSC. It also aims to reduce the maintenance costs of legacy services. This tutorial aims to help digital asset issuers and holders on the BNB Beacon Chain transfer the value of their assets, including BEP2/BEP8 tokens, before and after BC Fusion. By following this guide, users can avoid any potential losses of their valuable digital assets.

    NOTE: The BC Fusion program is scheduled for implementation in April 2024. Please ensure careful planning for the asset migration and keep the fund safe.

    "},{"location":"bc-fusion/users/assets/#before-bc-fusion","title":"Before BC Fusion","text":"

    Most valuable BEP2/BEP8 tokens such as BNB, BTC, and BUSD can freely move between the Beacon Chain and BSC networks. Users are strongly advised to transfer their assets to the BSC network to ensure a seamless and lossless transition, maintaining a 1:1 ratio. Of course, there are alternative channels available for asset transfers, such as utilizing centralized exchanges or decentralized cross-chain exchanges like Binance.com and Thorswap. However, these options are beyond the scope of this tutorial.

    Step1: Confirm if the Assets Support Cross-chain Transfers

    Open the Beacon Chain blockchain explorer, go to the BEP2 Asset page or BEP8 Asset page, and search for the token name to query it. Using BTC as an example, it is linked to a BSC Contract address, allowing for cross-chain transfers.

    In contrast to GTEX-71B, which lacks a BSC Contract address and thus does not support cross-chain transfers.

    If a user needs to transfer assets that don\u2019t support cross-chain transfers, it\u2019s strongly recommended to contact the token owner/issuer as soon as possible. Ask the token issuer to refer to the token bind tutorial for issuing BEP20 tokens on BSC and enabling cross-chain transfers. If the token issuer does not enable cross-chain transfer for the token before the sunset of BNB Beacon Chain, the funds will be lost forever and can not be recovered.

    Step2: Simply Transfer the Assets to the BSC Network

    BNB Chain Wallet and Trust Wallet mobile are suggested for this case. Taking BNB Chain Wallet as an example, once users import the accounts that have the tokens, they need to switch the network to \u201cBNB Beacon Chain Network\u201d:

    Then, select the asset to transfer, enter the BSC account and the token amount.

    The BSC wallet will receive the token after approximately one minute.

    For Trust Wallet mobile multi-chain wallet users, they can transfer their assets in the following way.

    Firstly, you need to open the Swap tab, choose From network as BNB Beacon Chain and To network as BNB Smart Chain, then find the asset you want to transfer and input the transfer amount. After you click the Continue button, it will redirect you to the approval page as below.

    Finally, the related asset will be transferred to BSC after you confirm the transaction.

    "},{"location":"bc-fusion/users/assets/#after-bc-fusion","title":"After BC Fusion","text":"

    Following the retirement of Beacon Chain, it is believed that some users have not yet transferred their assets to the BSC network. BNB Chain is still providing relief measures for these users: BEP299-Token Migration after BC Fusion.

    Although this solution has its limitations, it is important to note the following key points:

    1. It is only applicable to assets that have enabled cross-chain features. The BEP2/BEP8 assets will be permanently lost if not the case.

    2. Users are still responsible for securely storing their private keys on the Beacon Chain and using them for signing as proof.

    3. The process of recovering assets will take up to 7 days to complete.

    4. This solution is operated through the command line and does not provide any UI.

    Considering these limitations, it is highly recommended that users complete the token transfer before BC fusion as much as possible.

    The detailed guide for this solution will be published after the BC Fusion. Stay tuned for the update.

    "},{"location":"bc-fusion/users/bep153-stake-migration/","title":"BEP153 and LSD Stake Migration","text":""},{"location":"bc-fusion/users/bep153-stake-migration/#stake-migration-for-bep153","title":"Stake Migration For BEP153","text":"

    The BEP-153 has been introduced as a native staking protocol onto BNB Smart Chain before BNB Chain fusion. With this BEP, individual or institution delegators can stake BNB to specified validators and get staking rewards on the BSC side directly.

    However, underlying the protocol users\u2019 BNB are crosschain transferred to the Beacon Chain and then staked there. With the BNB Chain fusion, the delegators of BEP-153 needs to migrate their stakes to the new staking system.

    For BEP-153 stakes, the delegators need to undelegate, wait for the unbounding period (7 days), and then get their BNB back to stake on the new staking system.

    This document will guide you through the process of stake migration for BEP-153 delegators, including Liquid Staking Derivatives (LSD) protocol\u2019s users.

    "},{"location":"bc-fusion/users/bep153-stake-migration/#for-individual-delegators","title":"For Individual Delegators","text":"
    1. Open the Staking contract on BSCScan

    2. You can find your delegation information on the \u201cTransactions\u201d tab, or you can query the contract as the following:

    3. Undelegate your delegations by calling the undelegate function

    4. Afther the unbounding period (7 days), call the claimUndelegated function to get your BNB back

    5. Then you can delegate your BNB to the new staking system by following the new staking guide

    "},{"location":"bc-fusion/users/bep153-stake-migration/#for-lsd-protocol-delegators","title":"For LSD Protocol Delegators","text":"
    1. Go to your LSD protocol dApps and undelegate your delegations

    2. Wait for the unbounding period (7 days)

    3. Then you can delegate your BNB to the new staking system by following the new staking guide

    "},{"location":"bc-fusion/users/bep153-stake-migration/#for-lsd-protocol-projects","title":"For LSD Protocol Projects","text":"

    For LSD protocol projects, you MUST finish your undelegations before the Second Sunset Fork of Beacon Chain. In the Second Sunset Fork, all the delegations will automatically be returned to the delegator addressess. If your delegation address is not an EOA address, you will lose the control of your stakes and the fund will be lost.

    "},{"location":"bc-fusion/users/gov/","title":"Participate in Governance","text":""},{"location":"bc-fusion/users/gov/#governance-with-tally","title":"Governance with Tally","text":"

    This document provides a guide on how to participate in governance on the BNB Smart Chain (BSC) using Tally. It covers the process of delegating voting power, creating proposals, voting on proposals, and executing proposals.

    BNB Chain DAOs are created on Tally both for the mainnet and testnet.

    "},{"location":"bc-fusion/users/gov/#parameters","title":"Parameters","text":"

    There are several parameters which will affect the governance process on the BSC. Especially, the governance process on the BSC only enabled after enough voting power is migrated from the Beacon Chain to the BSC (i.e., the startGovThreshold parameter).

    Parameter Description Mainnet Value Testnet Value votingDelay a fixed duration after which users can vote to a proposal 0 hour 0 hour votingPeriod the voting period before tally 7 days 1 day proposalThreshold a fixed amount of gov BNB needed for a proposal 200 govBNB 100 govBNB quorumNumberRator the percentage of the total voting power required to produce a final vote result 10% 10% startGovThreshold the total supply of gov token to enable the gov function 10M BNB 10M BNB minPeriodAfterTheQuorum the time to add for voting when a proposal reaches quorum 1 day 1 hour timerlockDelay the timer locker duration to execute a proposal 1 day 6 hours"},{"location":"bc-fusion/users/gov/#governance-process-guide","title":"Governance Process Guide","text":"

    You need to connect to your Web3 wallet (e.g., TrustWallet, BEW, Metamask) for the following operations.

    "},{"location":"bc-fusion/users/gov/#delegate-voting-power","title":"Delegate Voting Power","text":"

    After you have delegated your BNB to a BSC validator, you can start participating in the BSC governance. To participate in BSC governance, you first need to delegate your voting power to someone or yourself if you wish to vote directly.

    You can click the My voting power button on the top right corner of the screen to delegate your voting power.

    You can delegate your voting power to yourself if you want to vote/create proposals directly, or to others if you want him/her to vote/create proposals on your behalf.

    If you delegate the voting power to yourself, you will see the current number of your voting power to participate in the governance.

    "},{"location":"bc-fusion/users/gov/#create-proposals","title":"Create Proposals","text":"

    If you have sufficient voting power (i.e., greater than the proposalThreshold), you can create proposals on the BSC network. Be noted that a user can only has one proposal in active/pending state at a time to prevent spamming.

    To create a proposal, click on the \u201cCreate new proposal\u201d button on the top right corner of the screen.

    After you have created a proposal, you can add a title, description, and a list of actions for the proposal.

    A text proposal only requires a title and a description, and it will not be executed by the network for there is no action.

    To add an action, click on the \u201cAdd action\u201d button, and fill in the details of the action.

    After you input all the details, click on the \u201cPublish\u201d will publish your proposal.

    You can also cancel a proposal by clicking on the \u201cCancel proposal\u201d button.

    "},{"location":"bc-fusion/users/gov/#vote-on-proposals","title":"Vote on Proposals","text":"

    Once a proposal is live (i.e., after the votingDelay and before the votingPeriod), you can cast your vote to support or oppose the proposal. To vote on a proposal, click on the \u201cVote on chain\u201d button.

    You can cast For, or Against, or Abstain votes to the proposal.

    "},{"location":"bc-fusion/users/gov/#execute-proposals","title":"Execute Proposals","text":"

    If a proposal reaches the quorum (i.e., reaches the quorumNumberRator of the total voting power) and it passes (i.e., more than 50% of the voted voting power supports the proposal), it can be executed by the network.

    To execute a proposal, fistly the proposal needs to be queued by clicking the Queue button.

    After the proposal is queued and exceeds the timelock duration (i.e, the timerlockDelay duration), it can be executed by anyone by clicking the Execute button.

    "},{"location":"bc-fusion/users/gov/#more-references","title":"More References","text":""},{"location":"bc-fusion/users/new-stake/","title":"Manage Your New Delegations","text":""},{"location":"bc-fusion/users/new-stake/#managing-new-stakes-with-bnb-staking-dapp","title":"Managing New Stakes with BNB Staking dApp","text":"

    Leverage the BNB staking dApp for streamlined management of your stakes. This guide provides a step-by-step walkthrough for using the dApp on both testnet and mainnet.

    "},{"location":"bc-fusion/users/new-stake/#connecting-your-wallet","title":"Connecting Your Wallet","text":"

    To interact with the dApp, first connect your web3 wallet. Currently, TrustWallet (mainnet only) and MetaMask are supported, along with any wallets compatible with WalletConnect.

    "},{"location":"bc-fusion/users/new-stake/#delegate-stakes","title":"Delegate Stakes","text":"
    1. Select a validator to delegate your stakes to. Detailed information about each validator is available on their respective pages.
    2. Click the Delegate button to initiate a new delegation.

    3. Enter the amount of BNB you wish to delegate.

    4. After confirming the delegation, your connected wallet will prompt you to sign the transaction. Successful transactions will be visible in the My Staking page, complete with transaction hash.

    "},{"location":"bc-fusion/users/new-stake/#redelegate-stakes","title":"Redelegate Stakes","text":"

    On the My Staking page, you can manage your existing delegations.

    Note: A redelegation fee of 0.002% applies to discourage frequent switching between validators.

    1. Click Redelegate to shift your stake to a different validator.

    2. In the ensuing popup, select your new validator and specify the amount to redelegate. You can opt to move the entire amount or just a portion.

    "},{"location":"bc-fusion/users/new-stake/#undelegate-stakes","title":"Undelegate Stakes","text":"

    To undelegate:

    1. Click the Undelegate button next to the relevant delegation.

    2. You can choose to undelegate the entire amount or a portion. Note that undelegated stakes are subject to a 7-day unbonding period before they are returned to your account.

    "},{"location":"bc-fusion/users/new-stake/#claim-stakes","title":"Claim Stakes","text":"

    After the unbonding period, you can claim your stakes by clicking the Claim button.

    "},{"location":"bc-fusion/users/new-stake/#faqs","title":"FAQs","text":""},{"location":"bc-fusion/users/new-stake/#which-wallet-can-be-used-to-delegate-to-the-new-validators","title":"Which wallet can be used to delegate to the new validators?","text":"

    Currently, MetaMask and TrustWallet (mainnet only) and are supported, along with any wallets compatible with WalletConnect.

    "},{"location":"bc-fusion/users/new-stake/#as-a-validator-operator-should-i-keep-both-the-original-validator-after-i-create-a-new-validator-on-the-bsc","title":"As a validator operator, should I keep both the original validator after I create a new validator on the BSC?","text":"

    It is recommended to keep both validators for a period of time to allow for smooth migration. It would be better to ask your delegators to migrate their stakes to the new validator. After your new validator is elected as cabinet or candidate, you can safely retire the old validator.

    "},{"location":"bc-fusion/users/new-stake/#how-should-i-migrate-my-delegations-if-my-bnb-was-delegated-through-the-bsc-smart-contract","title":"How should I migrate my delegations if my BNB was delegated through the BSC smart contract?","text":"

    Please refer to the stake migration guide for BEP153 delegations.

    "},{"location":"bc-fusion/users/stake-migration/","title":"Manage Your Old Delegations","text":""},{"location":"bc-fusion/users/stake-migration/#stake-migration","title":"Stake Migration","text":"

    The BNB Chain community has introduced BEP333: BNB Chain Fusion, a significant update that retires the BNB Beacon Chain from the ecosystem. This transition introduces native staking on the BNB Smart Chain, following the Feynman Hardfork. Stakeholders now have the opportunity to migrate their existing delegations to the new native staking system through two primary methods:

    Be noted, for delegations which are created in BEP-153 format, please refer to this document for the migration process.

    "},{"location":"bc-fusion/users/stake-migration/#cross-chain-redelegation","title":"Cross Chain Redelegation","text":"

    Cross chain redelegation allow users to migrate their delegations to BSC as delegations to native BSC validators, facilitaling users for easier migration compared to the second option. Therefore this is the recommended way for stake migration.

    "},{"location":"bc-fusion/users/stake-migration/#steps","title":"Steps","text":""},{"location":"bc-fusion/users/stake-migration/#step-1-find-your-delegations","title":"Step 1: Find your delegations","text":"

    Go to the staking website and connect to your web3 wallet.

    Mainnet Staking Website: https://www.bnbchain.org/en/staking

    Testnet Staking Website: https://testnet-staking.bnbchain.org/en/staking

    For testnet, you can BNB Chain Wallet to connect.

    For mainnet, you can use BEW or TrustWallet to connect.

    Open My Staking page, Then you can find you existing delegations as the following.

    "},{"location":"bc-fusion/users/stake-migration/#step-2-choose-the-native-bsc-validators-to-migrate-to","title":"Step 2: Choose the native BSC validators to migrate to.","text":"

    Choose one delegation and click Migrate to BSC button. The following window will be poped up for choosing which BSC valiadtor you want to migrate to.

    The window mainly contains the following fields:

    "},{"location":"bc-fusion/users/stake-migration/#setp-3-sign-the-migrate-transaction","title":"Setp 3: Sign the migrate transaction.","text":"

    Finally, you can sign the transaction and migration will be started.

    If the migration fails, the fund will be returned to your Beacon Chain, and you can check it in your web3 wallet.

    If the migration goes well, you will find the delegation in the new staking dApp. For how find your delegations, please refer to this document for more information.

    "},{"location":"bc-fusion/users/stake-migration/#undelegation-cross-chain-transfer-new-delegation","title":"Undelegation, Cross Chain Transfer, New Delegation","text":"

    The second option needs the delegator to 1) do undelegation on the Beacon Chain, wait the unboinding period, 2) cross chain transfer BNB to the BSC, and 3) stake in the new staking dApp. It needs more time and transaction fee, therefore it is not recommended.

    "},{"location":"bc-fusion/users/stake-migration/#steps_1","title":"Steps","text":""},{"location":"bc-fusion/users/stake-migration/#step-1-find-your-delegations_1","title":"Step 1: Find your delegations","text":"

    You can find your delegations as the steps in the option 1.

    "},{"location":"bc-fusion/users/stake-migration/#step-2-undelegate","title":"Step 2: Undelegate","text":"

    Then you can undelegate your delegations by click Undelegate button and send the transaction to the Beacon Chain.

    After the unbonding period (7 days in mainnet), the stake be returned to your Beacon Chain account.

    "},{"location":"bc-fusion/users/stake-migration/#step-3-cross-chain-transfer","title":"Step 3: Cross chain transfer","text":"

    You can use BNB Chain Wallet (BEW) or TrustWallet to cross chain transfer your BNB from the Beacon Chain to the BSC.

    For BEW, you need to switch the network to \u201cBNB Beacon Chain Network\u201d/\u201dBNB Beacon Chain Testnet Network\u201d:

    Then, select the asset to transfer, enter the BSC account and the token amount.

    The BSC wallet will receive the token after approximately one minute.

    For TrustWallet mobile multi-chain users, you need to open the Swap tab, and choose From network as BNB Beacon Chain and To network as BNB Smart Chain for mainnet asset transfer.

    Then find the asset you want to transfer and input the transfer amount.

    After you click the Continue button, it will redirect you to the approval page as below.

    Finally, the related asset will be transferred to BSC after you confirm the transaction.

    "},{"location":"bc-fusion/users/stake-migration/#step-4-delegate-to-new-validators","title":"Step 4: Delegate to new validators","text":"

    Finnally, you can delegate to the new BSC valdiators using the new staking dApp. You can refer to this document for the detailed steps.

    "},{"location":"bc-fusion/users/swaps/","title":"Manage Your Atomic Swaps","text":""},{"location":"bc-fusion/users/swaps/#atomic-swap-management","title":"Atomic Swap Management","text":"

    HTLC based atomic swaps are introduced in BEP3, to facilitate payment and asset exchanges between different blockchains. For BC fusion, in the first sunset hardfork, the creation and deposit of atomic swaps will be disabled, project owners (e.g., cross-chain exchanges, bridges) and users should be aware of this and take proactive steps.

    "},{"location":"bc-fusion/users/swaps/#query-atomic-swaps","title":"Query Atomic Swaps","text":"

    The atomic swap api is provided to query existing atomic swaps. Usually, user can provide a from address to query the related atomic swaps, for example:

    https://dex.bnbchain.org/api/v1/atomic-swaps?fromAddress=bnb1xz3xqf4p2ygrw9lhp5g5df4ep4nd20vsywnmpr

    The response will contain a lot of useful information, such as id of the swap, the asset of the swap, and other information.

    "},{"location":"bc-fusion/users/swaps/#handle-atomic-swaps","title":"Handle Atomic Swaps","text":""},{"location":"bc-fusion/users/swaps/#before-bc-fusion","title":"Before BC Fusion","text":"

    A user can proactively refund his/her atomic swaps by sending HTLC Refund transactions to Beacon Chain. The command to send such transaction is looks like this:

    ./bnbcli token refund --swap-id <swapID> --from <from-key> --chain-id Binance-Chain-Tigris --trust-node --node http://dataseed1.bnbchain.org:80\n

    If no proactive refunds are submitted, in the second sunset hardfork, all existing atomic swaps will be automatically refunded to the creators\u2019 accounts on Beacon Chain. The refund will proceed in many Beacon Chain blocks, depending on how many atomic swaps still exist on the blockchain. After refund, users should be able to find the assets in their accounts. Then users can handle the assets as other BEP2/BEP8 tokens. For how to cross transfer them to BNB Smart Chain, please refer to this tutorial.

    "},{"location":"bc-fusion/users/swaps/#after-bc-fusion","title":"After BC Fusion","text":"

    If the refunded assets are not transferred to BSC before the final sunset fork, users need to use the token-recover tool to get their binded BEP2/BEP8 assets. For more information, please refer to this tutorial.

    "},{"location":"bc-fusion/users/swaps/#for-atomic-swap-project-owers","title":"For Atomic Swap Project Owers","text":"

    Because in the first sunset hardfork, the creation and deposit of atomic swaps will be disabled, so project owners need to disable related functions in their projects IN ADVANCE and notify their uses to take proactive actions to refund their tokens.

    "},{"location":"bc-fusion/users/timelocks/","title":"Manage Your TimeLocks","text":""},{"location":"bc-fusion/users/timelocks/#timelock-management","title":"TimeLock Management","text":"

    A timelock is a feature that allows users to lock their assets for a certain period of time, which is introduced in (https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP9.md). For BC fusion, in the second sunset hardfork, all timelocks will be refunded to users\u2019 accounts. Users should proactively actionsj to transfer these assets to BSC after receiving the refunds.

    "},{"location":"bc-fusion/users/timelocks/#query-timelocks","title":"Query TimeLocks","text":"

    The time lock api is provided to query existing timelocks. Usually, user can provide a from address to query the related timelocks, for example:

    https://dex.bnbchain.org/api/v1/timelocks/bnb1rmet5j5pwc3xvhd82rwdjkvewzgmreh6we72sf

    The response will contain a lot of useful information, such as id of the timelock, the asset of the timelock, and the unlock time.

    "},{"location":"bc-fusion/users/timelocks/#handle-timelocks","title":"Handle TimeLocks","text":"

    Once the timelock is created, the owners cannot access their assets until the unlock time has passed. During the second sunset hardfork, all existing timelocks will be automatically refunded to the creators\u2019 accounts on Beacon Chain. The refund will proceed in many Beacon Chain blocks, depending on how many timelocks still exist on the blockchain. After refund, users should be able to find the assets in their accounts. Then users can handle the assets as other BEP2/BEP8 tokens. For how to cross transfer them to BNB Smart Chain, please refer to this tutorial.

    "},{"location":"bc-fusion/validators/creation/","title":"Create New Validators","text":""},{"location":"bc-fusion/validators/creation/#validator-creation-guide","title":"Validator Creation Guide","text":"

    This guide outlines the process for creating a new validator on the BNB Smart Chain (BSC). The BNB staking dApp is the official tool for creating and managing validators on the BSC.

    "},{"location":"bc-fusion/validators/creation/#terminology","title":"Terminology","text":""},{"location":"bc-fusion/validators/creation/#steps","title":"Steps","text":""},{"location":"bc-fusion/validators/creation/#1-connecting-to-the-dapp","title":"1. Connecting to the dApp","text":"

    Please connect to the staking dApp using your Operator Address. Trust Wallet, MetaMask, and WalletConnect options are available for the step. Make sure that the account has more than 2001 BNB before moving on to the next step.

    "},{"location":"bc-fusion/validators/creation/#2-filling-out-the-form","title":"2. Filling out the form","text":"

    Navigate to the dApp and select the Become a Validator button in the right middle of the page to initiate the creation process.

    The following information is required to create a validator.

    "},{"location":"bc-fusion/validators/creation/#basic-information","title":"Basic Information","text":"

    You\u2019ll need to provide the following details on the Create Validator page:

    To enhance your validator\u2019s visibility, consider uploading additional information to the BSC validator directory. Your avatar, once uploaded, will be displayed in the staking dApp.

    "},{"location":"bc-fusion/validators/creation/#addresses","title":"Addresses","text":"

    The following addresses are required:

    "},{"location":"bc-fusion/validators/creation/#generate-consensus-address","title":"Generate Consensus Address","text":"

    Download the BSC geth binary from the official release page.

    Note: Make sure you are downloading the correct binary based on your machine\u2019s platform, e.g., if you are using MacOS, you should download the geth_mac file. In the following, we will refer the binary as geth for simplicity.

    To create a new account for mining, please use the following command and set a password for the account.

    geth account new --datadir ${DATA_DIR}\n

    This command will return the public address (i.e. consensus address) and the path to your private key. Please backup the key file!

    An example consensus address is 0x4b3FFeDb3470D441448BF18310cAd868Cf0F44B5.

    If you already have an account for mining, you can use the seed phrase to recover the account.

    geth account import --datadir ${DATA_DIR}\n

    If you have created a validator on the Beacon Chain, please use a different one for the consensus address.

    "},{"location":"bc-fusion/validators/creation/#generate-vote-address-and-bls-proof","title":"Generate Vote Address and BLS Proof","text":"

    To create a new BLS account please use the following command.

     geth bls account new --datadir ${DATA_DIR}\n

    If you already have a voting key, create a bls wallet and use the keyfile to recover it, using the following command.

     geth bls account import ${KEY_FILE} --datadir ${DATA_DIR}\n

    Then you can get your vote address by running the following command.

    geth bls account list --datadir ${DATA_DIR}\n

    An example address is b5fe571aa1b39e33c2735a184885f737a59ba689177f297cba67da94bea5c23dc71fd4deefe2c0d2d21851eb11081f69.

    Then you can get your bls proof by running the following command.

    geth bls account generate-proof --chain-id ${BSC_CHAIN_ID} ${OPEATOR_ADDRESS} ${VOTE_ADDRESS}\n

    An example proof is 0xaf762123d031984f5a7ae5d46b98208ca31293919570f51ae2f0a03069c5e8d6d47b775faba94d88dbbe591c51c537d718a743b9069e63b698ba1ae15d9f6bf7018684b0a860a46c812716117a59c364e841596c3f0a484ae40a1178130b76a5.

    "},{"location":"bc-fusion/validators/creation/#create-indentity","title":"Create indentity","text":"

    Identity is used for assocaiting the new validator to the old validator created on the Beacon Chain, to facilitate delegators moving their stakes to the same validator operator when migrations. If you never create a validator in this page, you can leave it empty.

    Please download BC client binary from the official release page.

    Note: Make sure you are downloading the correct binary based on your machine\u2019s platform, e.g., if you are using MacOS, you should download the macos_binary.zip file, and after unzip it your will find bnbcli (for mainet) and tbnbcli(for testnet). In the following, we will refer the binary as bnbcli for simplicity.

    "},{"location":"bc-fusion/validators/creation/#setup-account","title":"Setup account","text":"

    If you have mnemonic, you can import your account by running the following command:

    $ ${workspace}/bin/bnbcli keys add <your-account-name> --recover --home ${HOME}/.bnbcli\nEnter a passphrase for your key:\nRepeat the passphrase:\n> Enter your recovery seed phrase:\n

    You will be asked to set a password for this account and input your mnemonic. After that, you will get your account info.

    Or if you have a ledger, you can import your account by running the following command:

    ${workspace}/bin/bnbcli keys add <your-account-name> --ledger --index ${index} --home ${HOME}/.bnbcli\n
    "},{"location":"bc-fusion/validators/creation/#get-identity","title":"Get identity","text":"

    After the account is imported, you can get your identity by running the following command:

    For local key:

    ${workspace}/bin/bnbcli \\\n  validator-ownership \\\n  sign-validator-ownership \\\n  --bsc-operator-address ${NEW_VALIDATOR_OPERATOR_ADDR_ON_BSC} \\\n  --from ${ACCOUNT_NAME} \\\n  --chain-id ${BC_CHAIN_ID} \\\n

    For ledger key:

    ${workspace}/bin/bnbcli \\\n  validator-ownership \\\n  sign-validator-ownership \\\n  --bsc-operator-address ${NEW_VALIDATOR_OPERATOR_ADDR_ON_BSC} \\\n  --from ${BSC_OPERATOR_NAME} \\\n  --chain-id ${CHAIN_ID} \\\n  --ledger\n

    And you will get the output like this:

    TX JSON: {\"type\":\"auth/StdTx\",\"value\":{\"msg\":[{\"type\":\"migrate/ValidatorOwnerShip\",\"value\":{\"bsc_operator_address\":\"RXN7r5XZlaljqzp8msZvx6Y6124=\"}}],\"signatures\":[{\"pub_key\":{\"type\":\"tendermint/PubKeySecp256k1\",\"value\":\"Ahr+LlBMLgiUFkP75kIuJW1YHrsTy39GeOdV+IaTREDN\"},\"signature\":\"AL5mj52s0+tcdoEb6c6PAmqBixuv3XEmrLW3Y1kvUeYgG3RqVvWU/dIVcfxiHHwLGXlcn0X1v00jFrpLIsxtqA==\",\"account_number\":\"0\",\"sequence\":\"0\"}],\"memo\":\"\",\"source\":\"0\",\"data\":null}}\nSign Message:  {\"account_number\":\"0\",\"chain_id\":\"Binance-GGG-Ganges\",\"data\":null,\"memo\":\"\",\"msgs\":[{\"bsc_operator_address\":\"0x45737baf95d995a963ab3a7c9ac66fc7a63ad76e\"}],\"sequence\":\"0\",\"source\":\"0\"}\nSign Message Hash:  0x8f7179e7969e497b5f3c006535e55c2fa5bea5d118a8008eddce3fccd1675673\nSignature: 0x00be668f9dacd3eb5c76811be9ce8f026a818b1bafdd7126acb5b763592f51e6201b746a56f594fdd21571fc621c7c0b19795c9f45f5bf4d2316ba4b22cc6da8\nPubKey: 0x021afe2e504c2e08941643fbe6422e256d581ebb13cb7f4678e755f886934440cd\n

    The Signature is your identity for associating to the old validator created on the Beacon Chain.

    "},{"location":"bc-fusion/validators/creation/#commissions","title":"Commissions","text":""},{"location":"bc-fusion/validators/creation/#self-delegation","title":"Self-delegation","text":""},{"location":"bc-fusion/validators/creation/#3-submitting-the-form","title":"3. Submitting the form","text":"

    Once you have filled out all the required information, click the Submit button to submit the transaction.

    "},{"location":"bc-fusion/validators/gov/","title":"Governance","text":""},{"location":"bc-fusion/validators/gov/#governance","title":"Governance","text":"

    BEP-297 introduces the native governance module for BNB smart chain after BNB chain fusion. The governance module is derived from OpenZeppelin Governor, with the following features:

    "},{"location":"bc-fusion/validators/gov/#workflow","title":"Workflow","text":"

    The workflow of the governance module consists of three stages: submit proposal, cast vote, and execute proposal. Each stage has its own requirements and parameters, which can be configured by the BNB smart chain governance too.

    "},{"location":"bc-fusion/validators/gov/#submit-proposal","title":"Submit Proposal","text":"

    To submit a proposal, a staking credit holder needs to send a propose transaction to the Governor contract, which is a system contract and the address is 0x0000000000000000000000000000000000002004, specifying the following information:

    A delegator should delegate more the 200 staked BNB as the minimal requirement for submitting a proposal. Meanwhile, a delegator can only submit a new propopal if there is no pending proposal created by him/her. The propose transaction will create a new proposal on the BNB smart chain. The proposal will have a unique proposal ID, and a proposal status of Pending. The proposal will then enter the voting period, which is the time window for the staking credit holders to cast their votes on the proposal.

    "},{"location":"bc-fusion/validators/gov/#cast-vote","title":"Cast Vote","text":"

    To cast a vote on a proposal, a staking credit holder needs to send a castVote transaction to the Governor contract, specifying the following information:

    The castVote transaction will record the support value and the voting power of the voter on the BNB smart chain. The voting power is the amount of staking credit that the voter has at the time of the vote. The voting power can change due to staking operations, such as delegate, undelegate, or redelegate, but the support value will remain the same. The voter can change their support value at any time during the voting period, by sending another castVote transaction with a different support value.

    After submitting a proposal, the staking credit holders can cast their votes on the proposal until the voting period ends. The voting period is one of the BNB smart chain governance parameters, and it is currently set to 7 days.

    "},{"location":"bc-fusion/validators/gov/#execute-proposal","title":"Execute Proposal","text":"

    To execute a proposal, anyone can send an execute transaction to the Governor contract, specifying the following information:

    The execute transaction will check the proposal status and the voting results on the BNB smart chain, and determine whether the proposal can be executed or not. The proposal can be executed if the following conditions are met:

    Once the voting period is over, the proposal can be executed if it meets the required conditions. However, the proposal cannot be executed immediately, as there is a time lock period before the proposal is executed. The time lock period is another BNB smart chain governance parameter, and it is currently set to 1 day. The time lock period is designed to prevent sudden and irreversible changes on the BNB smart chain, and to give the stakeholders a chance to react or prepare for the proposal execution.

    "},{"location":"bc-fusion/validators/gov/#voting-power-delegation","title":"Voting Power Delegation","text":"

    In addition to casting votes, the staking credit holders can also delegate their voting power to someone else to participate in governance on their behalf. This can be useful for staking credit holders who do not have the time, interest, or expertise to follow and vote on the proposals, but still want to have a say in the governance process. By delegating their voting power to a trusted party, such as a validator, a friend, or a professional service, they can benefit from their knowledge and experience, and also avoid the risk of losing their staking rewards due to abstaining from voting.

    To delegate their voting power, a staking credit holder needs to send a delegateVote transaction to the GovToekn contract, which is a system contract and the address is 0x0000000000000000000000000000000000002005, specifying the following information:

    The delegateVote transaction will record the delegation relationship and the voting power of the delegator on the BNB smart chain. The voting power is the amount of staking credit that the delegator has at the time of the delegation. The voting power can change due to staking operations, such as delegate, undelegate, or redelegate, but the delegation relationship will remain the same. The delegator can change their delegatee address at any time, by sending another delegateVote transaction with a different delegatee address.

    "},{"location":"bc-fusion/validators/key-management/","title":"Key Management","text":""},{"location":"bc-fusion/validators/key-management/#key-management-for-bsc-validators","title":"Key Management for BSC Validators","text":"

    BEP-294 and BEP-297 introduce the native staking and governance features for BNB Smart Chain (BSC). For a validator, when participating in staking (e.g., creating a validator, self-delegating) and governance, there are several wallet keys that will be involved. To help validators manage their keys and funds effectively and safely, the following practices are recommended.

    "},{"location":"bc-fusion/validators/key-management/#operator-key","title":"Operator Key","text":"

    The operator key is used for operating a validator, including creating a validator, editing the information of a validator, and undelegating. When creating a validator, the operator key is also used for self-delegating with more than 2001 BNB. When interacting with the new BSC staking dApp, the operator key is mostly involved.

    Be noted that the operator address can not be changed for a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet; when creating validators, there should be more than 2001 BNB in the operator account.

    "},{"location":"bc-fusion/validators/key-management/#staking-key","title":"Staking Key","text":"

    For a validator, it can also use another key, different from the operator key, to manage his/her delegation if needed. Then, such a staking key will be used to delegate/undelegate/redelegate to different validators and claim rewards. This key could be used frequently, depending on how a validator manages its delegations and rewards.

    Be noted that this key is optional, depending on the needs of a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet.

    "},{"location":"bc-fusion/validators/key-management/#consensus-key","title":"Consensus Key","text":"

    The consensus key is used for signing proposed blocks when mining blocks. No fund is needed for this account.

    Recommendation: Use a hot wallet so that it can be easily accessed by a validator node.

    "},{"location":"bc-fusion/validators/key-management/#fast-finality-vote-key","title":"Fast Finality Vote Key","text":"

    The fast finality vote key (BLS vote key) is used in the fast finality feature for signing votes of recently mined blocks. No fund is needed for this account.

    Recommendation: Use a hot wallet so that it can be easily accessed by a validator node.

    "},{"location":"bc-fusion/validators/key-management/#governance-vote-key","title":"Governance Vote Key","text":"

    The BEP-297 introduces the native BSC staking feature. A delegator (including validators for self-delegation) can delegate someone else to participate in governance on his/her behalf. When there is governance delegation, the governance vote key will be used for casting votes to BSC proposals. The related wallet should store some BNB for gas fees of the voting transaction.

    Be noted that this key is optional, depending on the needs of a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet.

    "},{"location":"bc-fusion/validators/migrations/","title":"Migrate Your Validators","text":""},{"location":"bc-fusion/validators/migrations/#validator-migration-guide","title":"Validator Migration Guide","text":"

    The introduction of native staking on the BNB Smart Chain marks a significant milestone, enabling validators to be directly created and managed on the chain. Following the Feynman hardfork, validators initially established on the BNB Beacon Chain are required to migrate to the BNB Smart Chain to continue their operations.

    To migrate your validator, you can take the following steps:

    "},{"location":"bc-fusion/validators/migrations/#1-create-a-new-validator","title":"1. Create a new validator","text":"

    The Staking dApp offers a user-friendly interface for creating a new validator on the BNB Smart Chain. Follow the detailed instructions in the validator creation guide to set up your new validator. It\u2019s crucial to populate the Identity field as specified in the guide to ensure a successful migration.

    "},{"location":"bc-fusion/validators/migrations/#2-migrate-stakes-to-the-new-validator","title":"2. Migrate stakes to the new validator","text":"

    Once your new validator is active, inform your delegators about the migration. They will need to migrate their stakes to your new validator to continue supporting you. For comprehensive details on stake migration, refer to the stake migration guide.

    "},{"location":"bc-fusion/validators/slash/","title":"Slash","text":""},{"location":"bc-fusion/validators/slash/#slash","title":"Slash","text":"

    The BNB smart chain (BSC) is a blockchain network that aims to provide fast, secure, and reliable transactions. To achieve this, the BSC relies on a set of validators who are responsible for producing and validating blocks. Validators stake their BNB tokens to participate in the network and earn rewards.

    However, validators also face the risk of losing their stakes if they behave in ways that could harm the network\u2019s integrity and reliability. This is where the slashing mechanism comes in. The slashing mechanism is a set of rules and functions implemented in the SlashIndicator contract (which is a system contract and the address is 0x0000000000000000000000000000000000001001) that penalizes validators for violating certain conditions. The SlashIndicator contract will also calls the StakeHub contract, another system contract with address 0x0000000000000000000000000000000000002002, for slashing.

    The slashing mechanism covers three types of offenses: downtime, double signing, and malicious voting. Each offense has a different severity and penalty, depending on the impact it has on the network. In this document, we will explain the slashing conditions and mechanisms for each offense in detail.

    "},{"location":"bc-fusion/validators/slash/#downtime-slash","title":"Downtime Slash","text":"

    Validators are expected to maintain high availability to ensure the network\u2019s smooth operation. Validators failing to meet these uptime requirements are subject to slashing.

    "},{"location":"bc-fusion/validators/slash/#double-sign-slash","title":"Double Sign Slash","text":"

    A critical offense within the BSC network is when a validator signs two different blocks at the same height. Such actions can lead to network forks, undermining the blockchain\u2019s security and consistency. Anyone can send a submitDoubleSignEvidence transaction to the SlashIndicator contract, specifying the following information:

    "},{"location":"bc-fusion/validators/slash/#malicious-fast-finality-vote-slash","title":"Malicious Fast Finality Vote Slash","text":"

    Validators who violates the fast finality vote rules will be also slashed. Anyone can send a submitFinalityViolationEvidence transaction to the SlashIndicator contract, specifying the following information:

    "},{"location":"bc-fusion/validators/staking/","title":"Staking","text":""},{"location":"bc-fusion/validators/staking/#staking","title":"Staking","text":"

    BNB smart chain (BSC) is a Proof-of-Staked-Authority (PoSA) blockchain, which means that staking is one of the most important parts of the system. BEP-294 introduces the new native staking mechanism after BNB chain fusion, which has several differences:

    In this section, we will explain the basic concepts and operations of staking on the BSC.

    "},{"location":"bc-fusion/validators/staking/#basic-concepts","title":"Basic Concepts","text":""},{"location":"bc-fusion/validators/staking/#consensus-engine","title":"Consensus Engine","text":"

    BSC uses a consensus mechanism which combines DPoS and PoA for consensus, so that:

    The staking mechanism is essential for determining the eligibility of validators to produce blocks.

    "},{"location":"bc-fusion/validators/staking/#validator-set","title":"Validator Set","text":"

    The validator set is the group of nodes that are responsible for validating transactions and producing blocks on the BSC. The validator set is determined by the amount of staking each validator has, which reflects the amount of BNB staked by the validator and its delegators. The top validators with the most staking are selected as the active validator set, and they take turns to propose and vote on blocks. The rest of the validators are in the standby validator set, and they can join the active validator set if their staking increases or if some active validators drop out.

    Any organization or individual can become part of the validator set by creating their validator on-chain and securing sufficient delegations. Similarly, they can opt-out by simply withdrawing all their BNB delegations.

    Validators can also be removed from the validator set by slashing, which is a penalty for misbehaving or being offline.

    "},{"location":"bc-fusion/validators/staking/#validator-election","title":"Validator Election","text":"

    There are different rols for validators:

    To determinate the roles of all validators, the validator set is updated every 24 hours, based on the latest staking information. At the first block after UTC 00:00, the consensus engine will sort all the validators and update the BSC validator set contract to save the ranking information. Be noted: during the BC fusion, the validators created on Beacon Chain and the validators created on BSC will be sorted together to decide the top validators. However, the validators created on BSC will receive triple voting power compared with the validators created on Beacon Chain for the same amount of BNB staked.

    "},{"location":"bc-fusion/validators/staking/#sytems-contracts","title":"Sytems Contracts","text":"

    There are several built-in contracts (i.e., system contracts) to facilitate the BSC staking.

    "},{"location":"bc-fusion/validators/staking/#credit-contract","title":"Credit Contract","text":"

    Each validator has its own validator contract that manages staking credit and facilitates the exchange between credit and BNB. The token name of a staking credit is \u201cstake {{validator moniker}} credit\u201d, and the symbol is \u201cst{{validator moniker}}\u201d. The contract will be created by the Stake Hub Contract when a validator is created.

    Whenever a user delegates BNB, an equivalent quantity of credit tokens are created. On the other hand, when a user withdraws their delegation, a corresponding amount of credit tokens are destroyed, thereby releasing the BNB.

    "},{"location":"bc-fusion/validators/staking/#reward-distribution","title":"Reward Distribution","text":"

    The staking reward comes from transaction fee - when a block is produced, the majority of the block fee will be collected as reward for the validator who proposed the block. Every day, a portion of the rewards collected will be directly sent to the operator account of the validator as commission, while the remaining portion will be sent to the corresponding validator credit contract. And when a user undelegates and claims his/her stakes, the accumulated reward and the original stake will be sent back to him/her.

    "},{"location":"bc-fusion/validators/staking/#validator-operations","title":"Validator Operations","text":"

    Validators are nodes running BNB Smart Chain software, participating in the consensus process. They require a minimum BNB stake at their validator address and can receive delegations from other BNB holders. Validators earn rewards from transaction fees and share most of these rewards with their delegators.

    "},{"location":"bc-fusion/validators/staking/#create-validator","title":"Create Validator","text":"

    To create a validator, a BNB holder needs to send a CreateValidator transaction to the StakeHub contract, which is a system contract and the address is 0x0000000000000000000000000000000000002002, with minimum amount of BNB that the validator needs to stake to their own validator address (2000 BNB), specifying the following information:

    The CreateValidator transaction will deduct the minimum self-delegation amount from the validator address and issue the corresponding staking credit to the validator. The validator will then join the standby validator set, and wait for the next validator set update to see if they can enter the active validator set.

    "},{"location":"bc-fusion/validators/staking/#edit-validator","title":"Edit Validator","text":"

    A validator can edit their validator information by sending EditConsensusAddress, EditCommissionRate, EditDescription, EditVoteAddress transactions to the StakeHub contract, specifying the following information accordingly:

    These transactions will update the validator information on the BNB smart chain, and the changes will take effect immediately. However, the new commission rate will only apply to the rewards earned after the transaction, and the previous rewards will be distributed according to the previous commission rate.

    "},{"location":"bc-fusion/validators/staking/#delegator-operations","title":"Delegator Operations","text":"

    Delegators are BNB holders who stake their BNB with a validator, sharing rewards. They can select any active or standby validator, switch between them, undelegate their BNB, and claim rewards anytime.

    "},{"location":"bc-fusion/validators/staking/#delegate","title":"Delegate","text":"

    To delegate BNB to a validator, a BNB holder needs to send a Delegate transaction to the StakeHub contract, specifying the following information:

    The Delegate transaction will deduct the amount of BNB from the delegator address and issue the corresponding staking credit to the validator. The validator will then share the rewards with the delegator, according to the commission rate.

    The credit tokens (or share) a delgator will get is calculated as - delegation amount * total supply of credit token / total pooled BNB. The total pooled BNB includes the delegation BNB and unclaimed reaward BNB of of the vlidator. It means that a delegator will get credit tokens based on the ratio of his/her delegation BNB amount to the total staked and reward BNB. When the validator gets block reward the total pooled BNB amount will increase, which means that when unbonding the delegator will get his delegation, as well as reward BNB from the pool.

    "},{"location":"bc-fusion/validators/staking/#redelegate","title":"Redelegate","text":"

    To redelegate BNB from one validator to another, a delegator needs to send a Redelegate transaction to the StakeHub contract, specifying the following information:

    The Redelegate transaction will deduct the amount of source validator staking credit and issue the corresponding dest validator staking credit to the user. The destination validator will then share the rewards with the delegator, according to the commission rate of the destination validator.

    The Redelegate transaction does not incur the unbonding period, but it will incur the redelegation fee, which is designed to prevent delegators from frequently switching between validators to chase the highest rewards or avoid the highest risks. The current fee rate is 0.002%.

    "},{"location":"bc-fusion/validators/staking/#undelegate","title":"Undelegate","text":"

    To undelegate BNB from a validator, a delegator needs to send an Undelegate transaction to the StakeHub contract, specifying the following information:

    The Undelegate transaction will burn the amount of staking credit from the user and moves the BNB to a withdraw queue. The BNB gets locked for an unbonding period before the delegator can claim it. The unbonding period is currently set to 7 days, and it is designed to prevent delegators from quickly withdrawing their BNB in case of a validator misbehavior or a network attack.

    "},{"location":"bc-fusion/validators/staking/#claim","title":"Claim","text":"

    To claim the unbond BNB and the rewards, a delegator should send a Claim transaction to the StakeHub contract, specifying the following information:

    The Claim transaction will return the delegated BNB and rewards to the delegator. Be noted, a delegator can only get the rewards after unbond. Before undelegation, the reward will be furthur staked to boost a delegator\u2019s income.

    "},{"location":"bnb-greenfield/","title":"BNB Greenfield","text":"BNB Greenfield

    BNB Greenfield is a cutting-edge decentralized storage and blockchain storage solution, designed to harness the power of decentralized technology in the field of data ownership and the data economy. The platform focuses on providing decentralized data management and access and EVM programmability, to revolutionize the data economy by simplifying the process of storing and managing data, while connecting data ownership with the DeFi context of BNB Chain.

    Get Started

    Dive into what is BNB Greenfield and start the journey with Greenfield.

    Build on Greenfield

    Start building dapps to create value based on the data assets and its related economy.

    EVM Programmability

    The real power of the Greenfield lies in its programmability to support the creation of value based on the data assets and its related economy.

    Greenfield Blockchain

    Get familiar with the Greenfield Blockchain and explore its main modules.

    Storage Provider

    Explore the Storage Provider.

    APIs and SDKs

    Utilize the APIs and SDKs to build the app

    "},{"location":"bnb-greenfield/introduction/","title":"Overview","text":""},{"location":"bnb-greenfield/introduction/#bnb-greenfield-overview","title":"BNB Greenfield Overview","text":"

    BNB Greenfield is a decentralized storage and blockchain storage solution platform that aims to revolutionize data ownership and the data economy.

    "},{"location":"bnb-greenfield/introduction/#what-is-bnb-greenfield","title":"What is BNB Greenfield","text":"

    BNB Greenfield is a cutting-edge decentralized storage and blockchain storage solution, designed to harness the power of decentralized technology in the field of data ownership and the data economy. The platform focuses on providing decentralized data management and access, to revolutionize the data economy by simplifying the process of storing and managing data, while connecting data ownership with the DeFi context of BNB Chain.

    What sets Greenfield apart from existing centralized and decentralized storage systems are its three key components:

    The ultimate goal of Greenfield is to establish a foundation for new data economy and dApp models, which will undoubtedly aid in the development and evolution of the foundation for Web3.

    "},{"location":"bnb-greenfield/introduction/#why-bnb-greenfield","title":"Why BNB Greenfield","text":"

    The cryptocurrency industry has experienced significant growth and adoption, with the likes of tokens, stablecoins, and DeFi covering various economic scenarios. However, certain areas like credit, real-world asset (RWA) tokenizations, and data remain inadequately innovated. Consequently, BNB Greenfield has been created to focus on data.

    A crucial issue that the BNB Greenfield project aims to address is that the value of a data asset is not self-evident when held by one person. The value of data assets increases when shared and leveraged by multiple parties, which stems from the ability to write, read, grant rights for sharing data, and even execute data to generate another. These abilities have financial traits that are tradable, and such trades can produce even more value and benefit two parties rather than just one.

    We foresee the need to create a new Web3 infrastructure for data, as two major features are still missing: a performant, convenient, and friendly decentralized storage infra, and the data-focused smart contract synergy. Hence, we aim to create \u201cBNB Greenfield,\u201d a new BNB side blockchain and relevant infrastructure that allows users and developers to:

    1. \u201clogin\u201d with anonymous cryptographic-based keys (IDs);

    2. create, read, share, and even execute data, with a user experience that is on par with the state-of-the-art cloud storage services today, and at a low cost;

    3. fully own their data assets and control who can use them and how;

    4. easily put their data assets into a wide, smart-contract-based economic context to gain financial value with them.

    In summary, BNB Greenfield seeks to offer users greater freedom in creating, owning, sharing, executing, and trading their data assets, while also providing transparency on how their data is owned and used.

    "},{"location":"bnb-greenfield/introduction/#how-bnb-greenfield-works","title":"How BNB Greenfield Works","text":"

    BNB Greenfield operates on two layers:

    1. It is built on a new, storage-focused blockchain; and

    2. It consists of a network of \u201cstorage providers\u201d.

    The BNB Greenfield Blockchain maintains the ledger for users and records the storage metadata as the common blockchain state data. Its native token for gas and governance is BNB, which is transferred from BNB Smart Chain. Additionally, BNB Greenfield blockchain has its own staking logic designed for governance.

    The Storage Providers (SP) are storage service infrastructures provided by organizations or individuals that use Greenfield as the ledger and the single source of truth. Each SP is responsible for responding to user requests to upload and download data, while also serving as the gatekeeper for user rights and authentications.

    Together, BNB Greenfield blockchain and the SPs comprise a decentralized object storage system that serves as the core of this new economy. Developers can construct decentralized applications (dApps) using the BNB Greenfield platform, which can act as client tools that facilitate user interactions with Greenfield; or applications that provide significant value to users\u2019 real lives using Greenfield as their infrastructure. These applications will use blockchain addresses as user identifiers and connect with features and smart contracts on the Greenfield blockchain, Greenfield SPs, and BNB Chain.

    A native cross-chain bridge exists between BSC and BNB Greenfield blockchain. While it is cheaper to create and access data on Greenfield, the relevant data operation can be transferred to BSC and integrated with DeFi smart contract systems to generate new business models.

    "},{"location":"bnb-greenfield/introduction/#ecosystem","title":"Ecosystem","text":"

    From Storage Providers and BNB staker to developers, there are a variety of individuals and entities that play a critical role in the growth and success of Greenfield. We\u2019ll dive into the unique contributions and responsibilities of each group, and explore how they work together to shape the future of Greenfield.

    "},{"location":"bnb-greenfield/introduction/#greenfield-actors","title":"Greenfield Actors","text":""},{"location":"bnb-greenfield/introduction/#validators","title":"Validators","text":"

    The Greenfield blockchain operates as a Proof-of-Stake (PoS) blockchain and has its own set of validators chosen through an election process based on PoS logic.

    The Validators have a vital responsibility of ensuring the security of the Greenfield blockchain. They are actively involved in the governance and staking of the blockchain, and their role is similar to other PoS blockchain networks. Additionally, they form a peer-to-peer network that plays a crucial role in the overall functioning of the blockchain.

    In addition to their governance responsibilities, validators also accept and process transactions, which enables users to operate on the objects stored on the Greenfield blockchain. They are responsible for maintaining the metadata of Greenfield and ensure that the blockchain state acts as a control panel for both Storage Providers (SPs) and users. Both parties rely on the validators to accurately update and utilize this state in order to operate, store, and access their object storage.

    "},{"location":"bnb-greenfield/introduction/#storage-providers-sps","title":"Storage Providers (SPs)","text":"

    Storage Providers (SPs) are a crucial part of the Greenfield blockchain. They offer storage service infrastructures to individuals and organizations. Using the Greenfield blockchain as the ledger and single source of truth, SPs maintain secure and reliable storage.

    Each Service Provider (SP) is accountable for handling user requests to upload and download data. They act as gatekeepers for user rights and authentications, which makes them integral in ensuring the security and accessibility of user data at all times.

    For further details on storage providers, kindly explore our dedicated Storage Provider\u2019s page.

    "},{"location":"bnb-greenfield/introduction/#greenfield-features","title":"Greenfield Features","text":""},{"location":"bnb-greenfield/introduction/#dapps","title":"dApps","text":"

    Greenfield dApps are applications that leverage the unique features of the Greenfield blockchain to solve various problems for their users. These dApps are designed to utilize Greenfield storage and related economic traits, providing a reliable and secure platform for creating and managing data.

    Users can interact with the BNB Greenfield Core Infrastructure through the use of BNB Greenfield dApps, which are decentralized applications that enable seamless interaction with the Greenfield ecosystem. Furthermore, the Greenfield blockchain provides an intuitive smart contract library on the cross-chain facility, making it easy for dApp developers to integrate these features into their applications. This user-friendly approach allows developers to efficiently build and deploy dApps that can solve real-world problems.

    "},{"location":"bnb-greenfield/introduction/#relayers","title":"Relayers","text":"

    The Greenfield Relayer is a powerful bi-directional relaying service designed to facilitate seamless communication between Greenfield and BSC/opBNB. It can only be operated by Greenfield validators and functions as a standalone process.

    This innovative system independently monitors and tracks cross-chain events that take place on both the Greenfield and BSC/opBNB networks, storing this data securely in a database. When an event is confirmed, the relayer generates a Boneh\u2013Lynn\u2013Shacham (BLS) signed message that is then shared through the P2P network on the Greenfield network, known as \u201cthe vote\u201d.

    As more votes are collected, the Greenfield Relayer assembles the necessary cross-chain package transaction and submits it to either the BSC/opBNB or Greenfield network. This streamlined process ensures that communication between the two networks is efficient and error-free.

    "},{"location":"bnb-greenfield/introduction/#challenge-verifier","title":"Challenge Verifier","text":"

    Challenge Verifier is an off-chain service that verifies data availability, data integrity and service quality by monitoring storage provider\u2019s activities. This mechanism works by penalizing and gradually eliminating storage providers with poor service quality, in order to ensure the good performance and reliability of the entire network.

    To elaborate, Challenge Verifier constantly checks the storage providers in the network by tasking them with challenges to prove their reliability. The challenges may include storing specific pieces of data or responding to requests within a certain time limit. Providers that fail these challenges will be punished by slash their staked BNB.

    By using Challenge Verifier, the network can ensure that only reliable and trustworthy storage providers are allowed to participate, protecting the network from any potential data loss, corruption, or low-quality service. Additionally, Challenge Verifier creates a competitive environment for storage providers, motivating them to continuously improve their services to avoid penalties and stay in the network.

    Challenge Verifier can only be operated by Greenfield validators right now, and will open to public in the future.

    "},{"location":"bnb-greenfield/introduction/#explore-and-participate-in-bnb-greenfield","title":"Explore and Participate in BNB Greenfield","text":""},{"location":"bnb-greenfield/core-concept/accounts/","title":"Accounts - BNB Greenfield Core Concepts","text":""},{"location":"bnb-greenfield/core-concept/accounts/#accounts","title":"Accounts","text":"

    Each Greenfield user has their own address as the identifier for his/her account. The addresses can create objects to store on Greenfield, bear and manage the permissions, and pay fees.

    Greenfield defines its account in the same format as BSC and Ethereum. It starts with ECDSA secp256k1 curve for keys and is compliant with EIP84 for full BIP44 paths. The root HD path for Greenfield-based accounts is m/44\u2019/60\u2019/0\u2019/0. In the readable presentation, a Greenfield address is a 42-character hexadecimal string derived from the last 20 bytes of the public key of the controlling account with 0x as the prefix.

    With this compatible address scheme, the users can reuse existing accounts and infrastructure from BSC on Greenfield. For example, they can use TrustWallet and Metamask (or other compatible wallets) to deposit their BNB from BSC to Greenfield and interact with dApps on Greenfield. It is also easy to identify the same owner by referring to the same addresses on both BSC and Greenfield.

    "},{"location":"bnb-greenfield/core-concept/accounts/#user-balance","title":"User Balance","text":"

    The account can hold a balance of BNB. These BNBs can be used to participate in staking, pay for gas fees of Greenfield transactions, and pay for Greenfield services.

    This balance can be added via native BNB transfer on Greenfield, or cross-chain transfer between Greenfield and BSC.

    "},{"location":"bnb-greenfield/core-concept/accounts/#account-definition","title":"Account Definition","text":"

    In the Greenfield, an account designates a pair of PubKey and PrivKey. The PubKey can be derived to generate various Addresses, which are used to identify users (among other parties) in the application.

    "},{"location":"bnb-greenfield/core-concept/accounts/#signatures","title":"Signatures","text":"

    The principal way of authenticating a user is done using digital signatures. Users sign transactions using their own private key. Signature verification is done with the associated public key. For on-chain signature verification purposes, we store the public key in an Account object (alongside other data required for a proper transaction validation).

    In the node, all data is stored using Protocol Buffers serialization.

    Greenfield only supports secp256k1 key schemes for creating digital signatures:

    Address length in bytes Public key length in bytes Used for transaction authentication Used for consensus (Tendermint) secp256k1 20 33 yes no"},{"location":"bnb-greenfield/core-concept/accounts/#addresses","title":"Addresses","text":"

    Addresses and PubKeys are both public information that identifies actors in the application. Account is used to store authentication information. The basic account implementation is provided by a BaseAccount object.

    To identify users, Greenfield uses the variable AccAddress. The address format follows ERC-55.

    "},{"location":"bnb-greenfield/core-concept/accounts/#key-management","title":"Key Management","text":"

    Greenfield blockchain is an application-specific chain without EVM. As a result, its transaction data structure and API are different from those of BSC. Greenfield will not support full functions in existing wallets, e.g. Transfer, Send Transactions, etc. However, these wallets can still sign transactions using the EIP712 standard. This standard allows wallets to display data in signing prompts in a structured and readable format. This is an example of how to use it in Metamask. Eventually, wallets will start supporting Greenfield directly.

    "},{"location":"bnb-greenfield/core-concept/accounts/#eip-712-support","title":"EIP-712 Support","text":"

    The greenfield chain supports and only supports EIP-712 structured transaction. These enable the existing wallet infrastructure to interact with Greenfield at the beginning naturally.

    To achieve this, the following changes have been made.

    1. An Ethereum-compatible RPC backend. Be noted that we only support necessary methods to connect a wallet(eth_chainId, eth_networkId, eth_blockNumber, eth_getBlockByNumber and eth_getBalance). Other RPC methods are not implemented.
    2. Same signing algorithm(eth_scep256k1) as Ethereum.

    For developers, they can refer to greenfield-go-sdk and greenfield-js-sdk for easy integration.

    "},{"location":"bnb-greenfield/core-concept/accounts/#keyring-interface","title":"Keyring Interface","text":"

    The Keyring interface is the primary interface for key management in the greenfield-cosmos-sdk. It defines the methods that a type needs to implement to be used as a key storage backend. These methods include:

    By implementing these methods, you can create a custom key storage backend that meets the specific needs of your application.

    Tip

    It means you don\u2019t have to follow the Keyring interface to manage your key, any existing Ethereum wallets are applicable to

    Greenfield as well.

    "},{"location":"bnb-greenfield/core-concept/accounts/#backend-options","title":"Backend Options","text":"

    The greenfield-cosmos-sdk provides different options for key storage, each with its own strengths and weaknesses. The choice of backend will depend on your specific use case. Here are the available options:

    "},{"location":"bnb-greenfield/core-concept/accounts/#system-options","title":"System Options","text":""},{"location":"bnb-greenfield/core-concept/accounts/#tools-options","title":"Tools Options","text":""},{"location":"bnb-greenfield/core-concept/accounts/#supported-sign-algorithms","title":"Supported Sign Algorithms","text":"

    The greenfield-cosmos-sdk supports as many sign algorithms as users want, but in Greenfield context, we only support eth_secp256k1 and ed25519. These algorithms were chosen for their security and compatibility with the Ethereum and Tendermint ecosystems.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/","title":"Billing and Payment - BNB Greenfield Core Concepts","text":""},{"location":"bnb-greenfield/core-concept/billing-payment/#billing-and-payment","title":"Billing and Payment","text":"

    In Greenfield, users are required to pay two different types of fees:

    The storage service fee will be charged on Greenfield in a steam payment style like Superfluid.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#storage-service-fee","title":"Storage Service Fee","text":"

    There are two kinds of storage service fees in Greenfield: object storage fee and data package fee.

    For storage, every object stored on Greenfield is charged at the price calculated by size, replica numbers, a base price ratio, and other parameters. Once the object is stored, the total charge of storage will be mainly only related to time and the base price.

    The storage fee calculation is:

    Storage Fee = sum(ChargedSize) * (PrimaryStorePrice + SecondaryStorePrice*SecondarySPNumber) * (1+Validator Tax Rate) * ReserveTime\n

    Users are granted a free, time-based quota for downloading data, with each bucket corresponding to a set of their objects. If the quota is exceeded, users can upgrade their data package to obtain an additional quota. The price for each data package is fixed for a certain period (unless the read price has been changed and the user takes some actions to reflect the price change), during which users will only be charged based on the amount of time they spend downloading and the package price. This charging scheme remains in effect until the user modifies their data package settings.

    The download quota fee calculation is:

    Download Quota Fee Fee = ChargedReadQuota * ReadPrice * (1 + Validator Tax Rate) * ReserveTime\n
    "},{"location":"bnb-greenfield/core-concept/billing-payment/#global-virtual-group-family-global-virtual-group","title":"Global Virtual Group Family & Global Virtual Group","text":"

    For storage fees, it will be not streamed to storage providers directly. It will be streamed to:

    When storage providers want to get their income, they can withdraw from Global Virtual Group Family and Global Virtual Group they are in. The validator tax pool cannot be controlled via any private key, and is used for challenge reward.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#payment-account","title":"Payment Account","text":"

    By default, the object owner\u2019s address will be used to pay for the objects it owns. But users can also create multiple \u201cpayment accounts\u201d and associate objects to different payment accounts to pay for storage and bandwidth.

    The address format of the payment account is the same as normal accounts. It\u2019s derived by the hash of the user address and payment account index. However, the payment accounts are only logical ones and only exist in the storage payment module. Users can deposit into, withdraw from, and query the balance of payment accounts on the Greenfield blockchain, but users cannot use payment accounts to perform staking or other on-chain transactions. Payment accounts can be set as \u201cnon-refundable\u201d. Users cannot withdraw funds from such payment accounts.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#paymaster","title":"Paymaster","text":"

    Besides using the owner\u2019s address or payment accounts to pay for the storage and bandwidth, users can also use others\u2019 address or payment account by setting the payment account for the bucket. The owner of payment account need to set the flow rate limit for the bucket before the bucket can be used.

    This will lower the barrier for users to use Greenfield since they don\u2019t need to have BNB to pay for the storage and bandwidth and they don\u2019t need to understand the charging mechanism of Greenfield which is quite complex.

    It will also provide a possibility for projects to sponsor the storage and bandwidth for their users.

    For more details, you can refer to the BEP of the paymaster.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#downgraded-service","title":"Downgraded service","text":"

    Once the payment accounts run out of BNB, the objects associated with these payment accounts will suffer from a downgraded service of downloading, i.e. the download speed and connection numbers will be limited. Once the fund is transferred to the payment accounts, the service quality can be resumed right away. If the service is not resumed for a long time, it is the SPs\u2019 discretionary decision to clear the data out, in a similar way to how SPs claim to stop services to certain objects. In such a case, the data may be gone from Greenfield completely.

    Warning

    If users fail to renew their subscription on time, there is a risk of their stored data being permanently deleted.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#trust-or-shift","title":"Trust or Shift","text":"

    In Greenfield, there is trust between the users and the SPs for data download.

    Since downloading bandwidth incurs additional fees and the download journal is not completely stored on the Greenfield blockchain, SPs offer an endpoint interface for users to access detailed logs and downloaders\u2019 signatures for download billing. If the users and the SPs cannot agree on the bill, users may just select another Primary SP.

    For more tech details, please refer to the stream payment module design.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#gas-and-fees","title":"Gas and Fees","text":"

    This document describes how Greenfield charge fee to different transaction types and the token economics of BNB Greenfield.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#introduction-to-gas-and-fees","title":"Introduction to Gas and Fees","text":"

    In the Cosmos SDK, gas unit is designated to track resource consumption during execution.

    On application-specific blockchains such as Greenfield, computational cost of storage is no longer the main factor in determining transaction fees, but rather, it is the incentive mechanism of Greenfield. For instance, creating and deleting a storage object use similar I/O and computational resources, but Greenfield encourages users to delete unused storage objects to optimize storage space, resulting in lower transaction fees.

    Greenfield Blockchain has taken a different approach from the gas meter design in Cosmos SDK. Instead, it has redesigned the gashub module to calculate gas consumption based on the type and content of the transaction, rather than just the consumption of storage and computational resources.

    Unlike networks like Ethereum, Greenfield transactions do not feature a gas price field. Instead, they consist of a fee and a gas-wanted field. The gas price is inferred during the transaction pre-execution process by fee/gas-wanted, and the transactions are queued based on the gas price, besides that the gas price should not be less than the minimum gas price on Greenfield: 5gwei.

    Warning

    This means that Greenfield does not refund any excess gas fees to the transaction sender.

    Therefore, when constructing transactions, it is important to exercise caution when specifying the fees.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#gashub","title":"GasHub","text":"

    All transaction types need to register their gas calculation logic to gashub. Currently, four types of calculation logic are supported:

    MsgGasParams_FixedType:

    type MsgGasParams_FixedType struct {\n    FixedType *MsgGasParams_FixedGasParams \n}\n

    MsgGasParams_GrantType:

    type MsgGasParams_GrantType struct {\n    GrantType *MsgGasParams_DynamicGasParams \n}\n

    MsgGasParams_MultiSendType:

    type MsgGasParams_MultiSendType struct {\n    MultiSendType *MsgGasParams_DynamicGasParams \n}\n

    MsgGasParams_GrantAllowanceType:

    type MsgGasParams_GrantAllowanceType struct {\n    GrantAllowanceType *MsgGasParams_DynamicGasParams \n}\n
    "},{"location":"bnb-greenfield/core-concept/billing-payment/#block-gas-meter","title":"Block Gas Meter","text":"

    ctx.BlockGasMeter() serves as the gas meter designed to monitor and restrict gas consumption per block.

    However, certain types of transactions may incur a high cost in Greenfield, leading to significant gas consumption. Consequently, Greenfield refrains from imposing any gas usage constraints on a block. Instead, Greenfield sets a block size limit, preventing blocks from exceeding 1MB in size and mitigating the risk of excessively large blocks.

    Info

    There is no gas limitation of a block on Greenfield Blockchain.

    "},{"location":"bnb-greenfield/core-concept/billing-payment/#fee-table","title":"Fee Table","text":"

    Please note that the gas fee can be updated through governance and may not be immediately reflected in this documentation.

    Msg Type Gas Used Gas Price Expected Fee(assuming BNB $200) /cosmos.auth.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.bank.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.consensus.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.crisis.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.crosschain.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.crosschain.v1.MsgUpdateChannelPermissions 0 5 gwei $0.00000000 /cosmos.distribution.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.gashub.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.gov.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.mint.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.oracle.v1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.slashing.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.staking.v1beta1.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.bridge.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.sp.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.storage.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.payment.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.challenge.MsgUpdateParams 0 5 gwei $0.00000000 /greenfield.permission.MsgUpdateParams 0 5 gwei $0.00000000 /cosmos.authz.v1beta1.MsgExec 1200 5 gwei $0.00120000 /cosmos.authz.v1beta1.MsgRevoke 1200 5 gwei $0.00120000 /cosmos.bank.v1beta1.MsgSend 1200 5 gwei $0.00120000 /cosmos.distribution.v1beta1.MsgSetWithdrawAddress 1200 5 gwei $0.00120000 /cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward 1200 5 gwei $0.00120000 /cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission 1200 5 gwei $0.00120000 /cosmos.feegrant.v1beta1.MsgRevokeAllowance 1200 5 gwei $0.00120000 /cosmos.gov.v1.MsgDeposit 1200 5 gwei $0.00120000 /cosmos.gov.v1.MsgSubmitProposal 2000000 5 gwei $2.00000000 /cosmos.gov.v1.MsgVote 2000000 5 gwei $2.00000000 /cosmos.gov.v1.MsgVoteWeighted 2000000 5 gwei $2.00000000 /cosmos.oracle.v1.MsgClaim 1000 5 gwei $0.00100000 /cosmos.slashing.v1beta1.MsgUnjail 1200 5 gwei $0.00120000 /cosmos.staking.v1beta1.MsgBeginRedelegate 1200 5 gwei $0.00120000 /cosmos.staking.v1beta1.MsgCancelUnbondingDelegation 1200 5 gwei $0.00120000 /cosmos.staking.v1beta1.MsgCreateValidator 2000000 5 gwei $2.00000000 /cosmos.staking.v1beta1.MsgDelegate 1200 5 gwei $0.00120000 /cosmos.staking.v1beta1.MsgEditValidator 2000000 5 gwei $2.00000000 /cosmos.staking.v1beta1.MsgUndelegate 1200 5 gwei $0.00120000 /greenfield.bridge.MsgTransferOut 1200 5 gwei $0.00120000 /greenfield.sp.MsgCreateStorageProvider 2000000 5 gwei $2.00000000 /greenfield.sp.MsgDeposit 1200 5 gwei $0.00120000 /greenfield.sp.MsgEditStorageProvider 2000000 5 gwei $2.00000000 /greenfield.sp.MsgUpdateSpStoragePrice 2000000 5 gwei $2.00000000 /greenfield.sp.MsgUpdateStorageProviderStatus 1200 5 gwei $0.00120000 /greenfield.storage.MsgCreateBucket 2400 5 gwei $0.00240000 /greenfield.storage.MsgDeleteBucket 1200 5 gwei $0.00120000 /greenfield.storage.MsgMirrorBucket 1200 5 gwei $0.00120000 /greenfield.storage.MsgUpdateBucketInfo 1200 5 gwei $0.00120000 /greenfield.storage.MsgCreateObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgSealObject 120 5 gwei $0.00012000 /greenfield.storage.MsgMirrorObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgRejectSealObject 12000 5 gwei $0.01200000 /greenfield.storage.MsgDeleteObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgCopyObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgCancelCreateObject 1200 5 gwei $0.00120000 /greenfield.storage.MsgUpdateObjectInfo 1200 5 gwei $0.00120000 /greenfield.storage.MsgDiscontinueObject 2400 5 gwei $0.00240000 /greenfield.storage.MsgDiscontinueBucket 2400 5 gwei $0.00240000 /greenfield.storage.MsgCreateGroup 2400 5 gwei $0.00240000 /greenfield.storage.MsgDeleteGroup 1200 5 gwei $0.00120000 /greenfield.storage.MsgLeaveGroup 1200 5 gwei $0.00120000 /greenfield.storage.MsgUpdateGroupMember 1200 5 gwei $0.00120000 /greenfield.storage.MsgUpdateGroupExtra 1200 5 gwei $0.00120000 /greenfield.storage.MsgRenewGroupMember 1200 5 gwei $0.00120000 /greenfield.storage.MsgMirrorGroup 1200 5 gwei $0.00120000 /greenfield.storage.MsgPutPolicy 2400 5 gwei $0.00240000 /greenfield.storage.MsgDeletePolicy 1200 5 gwei $0.00120000 /greenfield.storage.MsgMigrateBucket 1200 5 gwei $0.00120000 /greenfield.storage.MsgCancelMigrateBucket 1200 5 gwei $0.00120000 /greenfield.storage.MsgCompleteMigrateBucket 1200 5 gwei $0.00120000 /greenfield.payment.MsgCreatePaymentAccount 200000 5 gwei $0.20000000 /greenfield.payment.MsgDeposit 1200 5 gwei $0.00120000 /greenfield.payment.MsgWithdraw 1200 5 gwei $0.00120000 /greenfield.payment.MsgDisableRefund 1200 5 gwei $0.00120000 /greenfield.challenge.MsgSubmit 1200 5 gwei $0.00120000 /greenfield.challenge.MsgAttest 100 5 gwei $0.00010000 /greenfield.virtualgroup.MsgCreateGlobalVirtualGroup 1000000 5 gwei $1.00000000 /greenfield.virtualgroup.MsgDeleteGlobalVirtualGroup 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgDeposit 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgWithdraw 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgSettle 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgSwapOut 24000 5 gwei $0.02400000 /greenfield.virtualgroup.MsgCompleteSwapOut 24000 5 gwei $0.02400000 /greenfield.virtualgroup.MsgCancelSwapOut 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgReserveSwapIn 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgCancelSwapIn 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgCompleteSwapIn 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgStorageProviderExit 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgStorageProviderForcedExit 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgCompleteStorageProviderExit 1200 5 gwei $0.00120000 /greenfield.virtualgroup.MsgUpdateParams 1200 5 gwei $0.00120000 cosmos.authz.v1beta1.MsgGrant 800 + 800 per item 5 gwei $0.0008 per item cosmos.bank.v1beta1.MsgMultiSend 800 + 800 per item 5 gwei $0.0008 per item cosmos.feegrant.v1beta1.MsgGrantAllowance 800 + 800 per item 5 gwei $0.0008 per item

    For more details, you can refer to Greenfield Gas Params.

    "},{"location":"bnb-greenfield/core-concept/bnb-token-model/","title":"BNB Token Model - BNB Greenfield Core Concepts","text":""},{"location":"bnb-greenfield/core-concept/bnb-token-model/#bnb-token-model","title":"BNB Token Model","text":"

    BNB remains the main utility token on Greenfield. BNB can be transferred from BSC to Greenfield blockchain, and vice versa. It is used as:

    "},{"location":"bnb-greenfield/core-concept/bnb-token-model/#revenue-sharing","title":"Revenue Sharing","text":"

    The main economic drive of Greenfield comes from their storage providers who charge users fees for their storage services. Meanwhile, validators play a crucial role in supervising the network\u2019s security, maintaining stability and ensuring service quality. While validators may earn transaction fees, this alone may not be enough to guarantee sufficient staking for network security. Therefore, Greenfield has designed validators to receive a reasonable proportion of fees from the storage services they provide. This approach ensures that users\u2019 data is not only stored but that the network is also safe and secure.

    "},{"location":"bnb-greenfield/core-concept/bnb-token-model/#circulation-model","title":"Circulation Model","text":"

    In Greenfield, there is no inflation of BNB because of its dual-chain structure. Instead, cross-chain transfers are used to allow BNB to flow bi-directionally between Greenfield and Smart Chain. As a result, the total circulation of BNB on Greenfield can fluctuate.

    Greenfield use Lock/Unlock mechanism to ensure the total circulation of BNB on both chain is always less than the initial total supply:

    1. The transfer-out blockchain will lock the amount from source owner addresses into a module account or smart contract.

    2. The transfer-in blockchain will unlock the amount from module account or contract and send it to target addresses.

    3. Both networks will never mint BNB.

    Refer to cross chain model to get more details about the mechanism.

    "},{"location":"bnb-greenfield/core-concept/bnb-token-model/#genesis-setup","title":"Genesis Setup","text":"

    BNB is transferred from BSC to Greenfield as the first cross-chain action. The initial validator set and storage provider of Greenfield at the genesis will first lock a certain amount of BNB into the \u201cGreenfield Token Hub\u201d contract on BSC. This contract is used as part of the native bridge for BNB transferring after the genesis. These initial locked BNB will be used as the self-stake of validators, the deposit of storage provider and early days gas fees.

    The initial BNB allocation on greenfield is around 500K BNB.

    Tip

    No initial donors, foundation, or company will get funds in the genesis setup.

    "},{"location":"bnb-greenfield/core-concept/programmability/","title":"Cross-Chain Programmability - BNB Greenfield Cross Chain","text":""},{"location":"bnb-greenfield/core-concept/programmability/#cross-chain-programmability","title":"Cross-Chain Programmability","text":"

    The Greenfield ecosystem leverages cross-chain programmability to enhance data asset value through innovative permission management and smart code execution. This platform supports the creation, management, and operation of data-intensive, trustless computing environments across different blockchains.

    Info

    It does not mean developers have to build dapp based on BSC network. Excellent infrastructure, applications, and tools can be built directly on the Greenfield network.

    "},{"location":"bnb-greenfield/core-concept/programmability/#framework","title":"Framework","text":"

    The Greenfield ecosystem is structured into three primary layers, each serving a distinct purpose in facilitating cross-chain interactions and asset management.

    This layered architecture ensures robust cross-chain capabilities, enabling developers to create innovative applications while utilizing Greenfield\u2019s unique features.

    "},{"location":"bnb-greenfield/core-concept/programmability/#key-features","title":"Key Features","text":""},{"location":"bnb-greenfield/core-concept/programmability/#get-started-with-building-dapp","title":"Get Started with building dapp","text":""},{"location":"bnb-greenfield/core-concept/data-storage/data-availability/","title":"Data Integrity and Availability - BNB Greenfield Data Storage","text":""},{"location":"bnb-greenfield/core-concept/data-storage/data-availability/#data-integrity-and-availability","title":"Data Integrity and Availability","text":"

    There are three crucial aspects of data management: integrity, availability, and redundancy.

    Below are some key points to ensure each aspect is met: - The primary storage provider must correctly store the object uploaded by the user. - The assigned data segments in both primary and secondary storage providers must be free of any loss, corruption, or counterfeit data. - Erasure coding pieces in secondary providers should enable recovery of the original data in the primary storage provider.

    To ensure data integrity and redundancy, checksum and redundancy setups must be established for objects. These setups constitute part of the objects\u2019 metadata and must be verified by the storage providers and users upon creating objects. The metadata will be stored on the Greenfield blockchain.

    Collaboration between Greenfield and storage providers is crucial to ensure data integrity and availability, particularly in assigning data segments to primary and secondary storage providers. To increase user confidence that their data is stored as promised, Greenfield has introduced a \u201cProof-of-Challenge\u201d approach.

    Info

    \u201cProof-of-Challenge\u201d is proposed based on the assumptions: Greenfield is a self-sustained, service-oriented ecosystem.

    Stakeholders can trigger challenges in various ways, such as through users or via random events on the Greenfield blockchain. Following a challenge, Challenge Verifier must conduct an off-chain audit of challenged data from storage providers. The Verifier Consortium will vote on the challenge results, and the failed outcomes will reduce the corresponding storage providers\u2019 staked BNB. Participants who submitted the challenge and the verifier received rewards for their involvement in this process. Data that failed to pass a challenge will not face another challenge for a specific time to allow storage providers to restore the data.

    Data challenger module will elaborate further on challenges associated with data availability.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/","title":"Underlying Storage Model - BNB Greenfield Data Storage","text":"

    An object on the Greenfield is stored among multi-SPs like below, for example, 50MB:

    We will introduce some concepts about data storage before describing in detail.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#segment","title":"Segment","text":"

    Segment is the basic storage unit of an object. An object payload is composed of one or many segments in sequence. The segment size is globally configured on the Greenfield blockchain. The default segment size is 16MB. For larger objects, the payload data will be broken into many segments. If the object\u2019s size is less than 16MB, it has only one segment and the segment size is the same as the object\u2019s size.

    Please note the payload data of an object will be split into the same size segment but the last segment, which is the actual size. For example, if one object has a size 50MB, only the size of the last segment is 2 MB and the other segments\u2019 sizes are all 16MB.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#ec-chunk","title":"EC Chunk","text":"

    Erasure Code (EC) is introduced to get efficient data redundancy on Greenfield. A segment is the boundary to perform erasure encoding. Some EC chunks are generated by erasure encoding one segment at a time. EC strategy is globally configured on the Greenfield blockchain. The default EC strategy is 4+2, 4 data chunks, and 2 parity chunks for one segment. The data chunk size is \u00bc of the segment. As one typical segment is 16M, one typical data chunk of EC is 4M.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#piece","title":"Piece","text":"

    Piece is the basic storage unit for backend storage on Greenfield. Each segment or EC chunk can be regarded as one data piece. And the key for each piece is generated based on the policy on the Greenfield chain.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#primary-sp","title":"Primary SP","text":"

    Each bucket on the Greenfield is bound with one SP, which is called primary SP. And the user needs to select an SP as the primary SP when creating a bucket. For all the objects stored under the bucket, primary SP will store one complete copy, all segments of the objects\u2019 payload data. And only the primary SP serves users\u2019 read or download requests.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#secondary-sp","title":"Secondary SP","text":"

    EC chunks of an object payload data are stored on some SPs, which are called secondary SPs. Each secondary SP stores part of payload data, which is used for better data availability. The object payload can be recovered from EC chunks.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#redundancy-strategy","title":"Redundancy Strategy","text":"

    Redundancy strategy defines how an object payload is stored among SPs, which is globally configured on the Greenfield blockchain. Below is the current strategy: * The data stream of the file will be split into segments according to the granularity of the segment size. If the size of the data is less than the segment size, it will be split according to the size of the data itself. The default segment size is 16MB; * Greenfield uses Reed-Solomon algorithm Reed-Solomon as its EC strategy, the default data blocks are 4, and the default parity blocks are 2 . * All the segment pieces of an object are stored on the Primary SP; * After EC encoding with the segment, the EC encoding module will generate six EC chunk pieces. All the EC chunk pieces of the segment will be stored to the six chosen secondary SPs.

    For example, when processing a 32MB file, the object is split into two segments. These two segments are stored in the primary storage provider, and each segment is encoded using erasure coding to generate six 4MB pieces. These six pieces are stored in six secondary storage providers in numerical order.

    "},{"location":"bnb-greenfield/core-concept/data-storage/data-storage/#integrity-hash","title":"Integrity Hash","text":"

    The integrity hashes include a root hash of the primary SP and several root hashes for each secondary SP which based on the EC strategy. The number of secondary hashes is equal dataBlocks plus parityBlock (it is six for now). Each piece\u2019s hash is computed by using hash algorithm (default is sha256) on the data piece\u2019s content. The pieces\u2019 root hash is computed based on all the pieces\u2019 hashes.

    The calculation process can be represented as follows:

    // secondaryHashN represents the Integrity Hash calculated by the Nth secondary SP.\n// segmentN_pieceN represents the Nth piece of the Nth segment of the object after EC encoding\nIntegrityHashes = [primaryHash, secondaryHash1 ...secondaryHash6]\nprimaryHash := hash(hash(segment1)+hash(segment2)..+hash(segmentN))\nsecondaryHashN := hash(hash(segment1_pieceN)+hash(segment2_pieceN)..+hash(segmentN_pieceN))\n
    For example, when processing a 32MB file, we got two segments called segment1 and segment2. The integrity hash of the primary SP is equal with hash(hash(segment1) + hash(segment2)). For each secondary SP, it stored piece1 and piece2 which is the encoding result by the segments. The integrity hash of the first secondary SP is equal with hash(hash(segment1_piece1) + hash(segment2_piece1)).

    Integrity hash is an important metadata of objects on the chain. During the process of creating an object, the integrity hash of each object is calculated and this information is recorded on the blockchain to ensure the accuracy of the data.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/","title":"Simple Storage Service - BNB Greenfield Data Storage","text":""},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#simple-storage-service","title":"Simple Storage Service","text":"

    Greenfield Simple Storage Service offers developers comparable API primitives and storage models to the AWS S3 cloud storage which is most utilized in Web2.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#features","title":"Features","text":""},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#storage-management","title":"Storage Management","text":"

    Greenfield has storage management features thart you can use to manage your resources, such as buckets, objects and groups. All the metadata of the resources are on-chain and can be only changed through transactions onto the greenfield blockchain.

    for more information, see Storage Module Design.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#permission-management","title":"Permission Management","text":"

    Greenfield Providers features for managing permissions to your buckets and objects. By default, Greenfield buckets and the objects in them are private. You only has the permissions to the resources you create. To grant granular resource permissions that support your specific use case of your resources, you can use the following features:

    for more information, see Permission Module Design.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#keys","title":"Keys","text":""},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#bucket","title":"Bucket","text":"

    In Greenfield, a bucket is a virtual container for storing objects. Users must assign each bucket a unique name that complies with DNS naming conventions, consisting of one or more labels separated by periods. It\u2019s crucial that the bucket name be globally unique within the Greenfield namespace to prevent two buckets from sharing the same name. Here are the bucket name rules for Greenfield:

    Once a bucket has been created, objects can be uploaded to it using various methods such as the gnfd command line or the SDKs. Objects within a bucket can be organized and managed like folders (also called \u201cprefixes\u201d). Additionally, it\u2019s possible to assign a unique key (a string value) to each object within the bucket to distinguish it from other objects.

    Every user account can create several buckets. The account will become the \u201cowner\u201d of the bucket.

    Each bucket should be associated with its own Primary SP, and the payment accounts for Read and Store functions. The owner\u2019s address will be the default payment account.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#object","title":"Object","text":"

    An object is a fundamental unit of storage in Greenfield, which represents a file consisting of data and its associated metadata. Each object is uniquely identified within a bucket by its object name (a string value). Here are the object name rules for Greenfield:

    While objects are commonly used to store files, they can contain any type of data, including text, images, videos, and program binaries.

    Users can upload objects to Greenfield using various methods, including the gnfd command line and SDKs. They can also download, copy, or move objects in a similar way.

    Objects in Greenfield have several important characteristics, including: - name and ID - owner - bucket that hosts it - size and timestamps - content type - checkSums for the storage pieces - storage status - associated SP information

    Object metadata is stored with the bucket name as the prefix of the key. It is possible to iterate through all objects under the same bucket, but it may be a heavy-lifting job for a large bucket with lots of objects.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#group","title":"Group","text":"

    A Group is a collection of accounts with the same permissions. Here are the group name rules for Greenfield:

    The group name is not allowed to be duplicated under the same user. However, a group can not create or own any resource. A group can not be a member of another group either.

    A resource can only have a limited number of groups associated with it for permissions. This ensures that the on-chain permission check can be finished within a constant time.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#group-member","title":"Group Member","text":"

    A Group Member is an account that is associated with a group. A group member can be added to multiple groups. Group Member has a expiration time which is set by the group owner. After the expiration time, the group member will still in the group, but the permission will be revoked.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#resource-based-policy","title":"Resource-Based Policy","text":"

    The user can use Resource-Based Policy to grant permissions to other accounts. Any resources, such as buckets, objects and groups, can associate several policy. Only the resource owner can put a policy which associate to a resource he owned.

    In the reousrce-based policy, the user can use wildcard characters Greenfield Resource Names(GRNS) and other values to grant permission to a subset of objects. For Example, the user can only allow the grantee to access to the objects that begin with a common prefix or end with a given extension, such as .html.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#life-cycle","title":"Life Cycle","text":"

    To store your data in Greenfield, the user should work with resources known as buckets and objects. A bucket is a container for objects, and an object is a file along with any metadata that describes that file.

    To store an object in Greenfield, the user creates a bucket and then uploads the object to that bucket. Once the object is in the bucket, it can be opened, downloaded, and moved. When the user no longer needs an object or a bucket, they can clean up their resources.

    "},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#bucket_1","title":"Bucket","text":""},{"location":"bnb-greenfield/core-concept/data-storage/simple-storage-service/#object_1","title":"Object","text":""},{"location":"bnb-greenfield/for-developers/bundle-service/","title":"Bundle Service - BNB Greenfield Develop","text":"

    With more and more developers joining BNB Greenfield ecosystem, many good practices utilizing decentralized storage continue to emerge. On the other hand, sending small files to Greenfield is not an economic way. When small files are sent, the information about the files (metadata) saved in the system can be bigger than the files themselves. This means it costs more for both the users and Greenfield. For instance, imagine a user\u2019s account wants to uploads a website to Greenfield. If the files of the website are tiny but there are a lot of them, it leads to the same problem: too much metadata and higher costs.

    BNB Chain has proposed the core protocol for the Greenfield bundle to solve this problem. You can find more details about BEP-323. NodeReal is the first infrastructure provider to implement the bundling service. Bundling service provides a solution to combine small files together into one big file before sending it to Greenfield. Thus, developers can can cut down unnecessary costs while still get to each file in the big file as if they were separate.

    NodeReal Bundling service is fully open sourced, developers can use NodeReal bundle service directly, while they can also deploy their own bundle service if needed.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#bundle-format","title":"Bundle Format","text":"

    The bundle format specifies the structure and organization of the bundle that users create when packing files. This format is designed to pack flat files; hierarchical directory structures, or folders, are not supported.

    When dealing with a folder, we can simplify its structure by turning it into a series of individual files. As part of this process, we rename each file to include the folder path. For example, a file originally named file.txt inside the nested folders dira and dirb would be renamed to dira/dirb/file.txt. This approach allows us to maintain the organization of the folder while conforming to the requirement for flat files in the bundle.

    The bundle format is structured into several key components as follows:

    For more details, you can refer to the BEP-323 and Bundle-SDK.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#bundle-service","title":"Bundle Service","text":"

    With the bundle format above, users now can pack their small objects into a bundle and upload the bundle file to Greenfield. But users can not visit the objects in the bundle file conveniently.

    The bundle service is designed to serve the users or dApps uploading a lot of small objects to Greenfield and provide an indexing service for the objects in the bundle. Users can upload small objects to the bundle service and the bundle service will pack the small files into a bundle and upload it to Greenfield, at the same time, the bundle service will also provide a URL to visit each object in the bundle file.

    The bundle service will upload the bundle file to the bucket that the user specified, so the user should grant the account of the bundle service permission to upload files to the bucket. Meanwhile, the user should also grant the transaction fee for the bundle service to upload objects to Greenfield.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#architecture","title":"Architecture","text":"

    The bundle service contains two main components: API service and Bundler.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#api-service","title":"API Service","text":"

    The API service will serve users\u2019 requests like uploading an object, querying an object, etc.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#bundler","title":"Bundler","text":"

    The bundler will pack the objects that the user uploaded into a bundle file and upload it to a bucket in Greenfield.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#main-workflows","title":"Main Workflows","text":"

    It is important to understand that the Bundler service uploads bundled files to the user\u2019s bucket, the user has absolute control over the bundle files. This level of control allows users to manage and manipulate their bundled files as needed effectively.

    The bundle service utilizes its own account to send transactions and submit bundled files to Greenfield. Users are responsible for covering the transaction fees, and they need to grant authorization to the bundler account to create new files under their bucket. Therefore, it is essential to complete the necessary authorization before using the bundler service.

    Greenfield can manage permissions for buckets and files. However, to keep the bundler service streamlined, complex permission management is currently not available. The bundler service only supports public buckets, allowing only the bucket owner to upload files. However, all users can access the files through the bundler service with no authorization.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#grant-permission","title":"Grant Permission","text":""},{"location":"bnb-greenfield/for-developers/bundle-service/#upload-object","title":"Upload Object","text":"

    The bundle will be frozen if any of the following conditions are met: - The size of the bundle is equal to or greater than the MaxBundledSize, which has a default value of 1GB. - The number of objects in the current bundle is equal to or greater than the MaxBundledNumber, which has a default value of 1000. - The time interval since the creation of the bundle is equal to or greater than the MaxFinalizeTime, which has a default value of 24 hours.

    Users can also define their own rules for MaxBundledSize , MaxBundledNumber , and MaxFinalizeTime , but the values should not exceed the default ones.

    In this mode, when the previous bundle is frozen, if there are any new files uploaded, the bundler service will automatically create a new bundle for the user, eliminating the need for any additional user intervention. The bundles created by the bundler service follow the naming format of {bundle_prefix}_{bundle_nonce} . The bundle_prefix is bundle by default, and bundle_nonce is the number of bundles created in the bucket.

    In addition, users have the option to fully specify the lifecycle of a bundle by creating a new bundle using the \u201ccreate bundle\u201d API and then requesting to submit the bundle to Greenfield through the \u201cseal bundle\u201d API. It is important to note that the time from bundle creation to sealing should not exceed the DeaultMaxBundledTime of 24 hours. If this time limit is exceeded, the bundle service will automatically set the bundle as expired and the user can not finalize the bundle anymore.

    The bundler service is primarily designed to address the storage performance and efficiency issues associated with small files. Therefore, it is important to note that the file size uploaded to the bundle service should not exceed 16 MB. Any file exceeding this limit will be rejected by the bundle service.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#upload-bundle","title":"Upload Bundle","text":"

    Since users may want to upload files at the same time like uploading a website, the bundle service allows users to upload a valid bundle. You can use the bundle commandline tool to easily combine small objects into a bundle.

    The bundle service will validate the uploaded bundle, if the bundle is invalid, the request will be rejected.

    For the valid bundle, it will index all the files in the bundle so the user can visit the files in the bundle like the objects uploaded via UploadObject API.

    Unlike the UploadObject API, the user must specify the bundle name when uploading a bundle and the user are not allowed to upload objects to this bundle any longer. The bundle will be marked as Finalized and it will be uploaded to Greenfield by the bundle service.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#query-object","title":"Query Object","text":"

    The Bundle service stores index information for uploaded objects. It tracks the bundle and its metadata, making it easy to locate and index files bundled on Greenfield. The service also caches frequently accessed data to improve request performance. - When the bundler service has the file saved, the bundler service can respond to the request immediately. - If only the index information is available, the bundle service retrieves the file from Greenfield and returns it to the user. - If the index is missing, the service attempts to rebuild it from Greenfield and then retrieves and returns the file.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#apis","title":"APIs","text":"

    The Bundle Service Server API provides several endpoints for managing and interacting with bundles. Here\u2019s a brief overview:

    For more detailed information about each endpoint, including required parameters and response formats, please refer to the swagger.yaml file in https://github.com/node-real/greenfield-bundle-service.

    For detailed usage cases, you can refer to the e2e test cases in https://github.com/node-real/greenfield-bundle-service/tree/main/e2e.

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#endpoints","title":"Endpoints","text":"

    Opensource implement from NodeReal

    "},{"location":"bnb-greenfield/for-developers/bundle-service/#greenfield-testnet","title":"Greenfield Testnet","text":"

    Using the testnet\u2019s bundle service, the bundle file will be uploaded to the Greenfield testnet. Endpoint:

    https://gnfd-testnet-bundle.nodereal.io\n
    "},{"location":"bnb-greenfield/for-developers/bundle-service/#greenfield-mainnet","title":"Greenfield Mainnet","text":"

    Using the mainnet\u2019s bundle service, the bundle file will be uploaded to the Greenfield mainnet. Endpoint:

    https://gnfd-mainnet-bundle.nodereal.io\n
    "},{"location":"bnb-greenfield/for-developers/get-started-dev/","title":"Quick Guide - BNB Greenfield Develop","text":"

    Here\u2019s a quick guide to get you from zero to hero. This doc provides a guide to the following ideas:

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#greenfield-programmability-concepts","title":"Greenfield & Programmability Concepts","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#greenfield-101","title":"Greenfield 101","text":"

    Read Greenfield Overview here

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#uniform-address-format","title":"Uniform Address Format","text":"

    Greenfield defines its account in the same format as BSC and Ethereum. It starts with ECDSA secp256k1 curve for keys and is compliant with EIP84 for full BIP44 paths.

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#account-operation","title":"Account Operation","text":"

    Create a greenfield account, deposit BNB, and program token transfers.

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#data-storage","title":"Data storage","text":"

    Create a public bucket to upload and share objects.

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#permission-control","title":"Permission control","text":"

    Create a private bucket and share it with specific individuals.

    "},{"location":"bnb-greenfield/for-developers/get-started-dev/#enhanced-permission-control","title":"Enhanced permission control","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#cross-chain-programmability","title":"Cross-chain Programmability","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#developer-starter-kit","title":"Developer Starter Kit","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#api","title":"API","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#sdk","title":"SDK","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#setup","title":"Setup","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#developer-resource","title":"Developer Resource","text":""},{"location":"bnb-greenfield/for-developers/get-started-dev/#storage-onramp","title":"Storage onramp","text":"

    https://dcellar.io/

    "},{"location":"bnb-greenfield/for-developers/interact-node/","title":"Interact with the Chain - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-developers/interact-node/#interact-with-the-chain","title":"Interact with the Chain","text":"

    There are multiple ways to interact with a node: using the CLI, using gRPC or using the REST endpoints.

    Info

    Since Greenfield Blockchain is based on Cosmos, The majority of the content in this page is copied from the Cosmos SDK.

    "},{"location":"bnb-greenfield/for-developers/interact-node/#using-the-cli","title":"Using the CLI","text":"

    Now that your chain is running, it is time to try sending tokens from the first account you created to a second account. In a new terminal window, start by running the following query command:

    gnfd query bank balances $MY_VALIDATOR_ADDRESS \n

    You should see the current balance of the account you created, equal to the original balance of BNB you granted it minus the amount you delegated via the gentx. Now, create a second account:

    gnfd keys add recipient --keyring-backend test\n\n# Put the generated address in a variable for later use.\nRECIPIENT=$(gnfd keys show recipient -a --keyring-backend test)\n

    The command above creates a local key-pair that is not yet registered on the chain. An account is created the first time it receives tokens from another account. Now, run the following command to send tokens to the recipient account:

    gnfd tx bank send $MY_VALIDATOR_ADDRESS $RECIPIENT 1000000BNB  --keyring-backend test\n\n# Check that the recipient account did receive the tokens.\ngnfd query bank balances $RECIPIENT \n
    "},{"location":"bnb-greenfield/for-developers/interact-node/#using-grpc","title":"Using gRPC","text":"

    The Protobuf ecosystem developed tools for different use cases, including code-generation from *.proto files into various languages. These tools allow the building of clients easily. Often, the client connection (i.e. the transport) can be plugged and replaced very easily.

    Since the code generation library largely depends on your own tech stack, we will only present three alternatives:

    "},{"location":"bnb-greenfield/for-developers/interact-node/#grpcurl","title":"grpcurl","text":"

    grpcurl is like curl but for gRPC. It is also available as a Go library, but we will use it only as a CLI command for debugging and testing purposes. Follow the instructions in the previous link to install it.

    Assuming you have a local node running (either a localnet, or connected a live network), you should be able to run the following command to list the Protobuf services available (you can replace localhost:9000 by the gRPC server endpoint of another node, which is configured under the grpc.address field inside app.toml:

    grpcurl -plaintext localhost:9090 list\n

    You should see a list of gRPC services, like cosmos.bank.v1beta1.Query. This is called reflection, which is a Protobuf endpoint returning a description of all available endpoints. Each of these represents a different Protobuf service, and each service exposes multiple RPC methods you can query against.

    In order to get a description of the service you can run the following command:

    grpcurl \\\n    localhost:9090 \\\n    describe cosmos.bank.v1beta1.Query                  # Service we want to inspect\n

    It\u2019s also possible to execute an RPC call to query the node for information:

    grpcurl \\\n    -plaintext\n    -d '{\"address\":\"$MY_VALIDATOR\"}' \\\n    localhost:9090 \\\n    cosmos.bank.v1beta1.Query/AllBalances\n
    "},{"location":"bnb-greenfield/for-developers/interact-node/#query-for-historical-state-using-grpcurl","title":"Query for historical state using grpcurl","text":"

    You may also query for historical data by passing some gRPC metadata to the query: the x-cosmos-block-height metadata should contain the block to query. Using grpcurl as above, the command looks like:

    grpcurl \\\n    -plaintext \\\n    -H \"x-cosmos-block-height: 279256\" \\\n    -d '{\"address\":\"$MY_VALIDATOR\"}' \\\n    localhost:9090 \\\n    cosmos.bank.v1beta1.Query/AllBalances\n

    Assuming the state at that block has not yet been pruned by the node, this query should return a non-empty response.

    "},{"location":"bnb-greenfield/for-developers/interact-node/#programmatically-via-go","title":"Programmatically via Go","text":"

    The following snippet shows how to query the state using gRPC inside a Go program. The idea is to create a gRPC connection, and use the Protobuf-generated client code to query the gRPC server.

    "},{"location":"bnb-greenfield/for-developers/interact-node/#install-greenfield-go-sdk","title":"Install Greenfield GO-sdk","text":"

    Refer to Go-sdk doc to install the latest dependency.

    Init client without key manager, you should use it for only querying purpose.

    client := NewGreenfieldClient(\"localhost:9090\", \"greenfield_9000-121\")\n\nquery := banktypes.QueryBalanceRequest{\n    Address: \"0x76d244CE05c3De4BbC6fDd7F56379B145709ade9\",\n    Denom:   \"BNB\",\n}\nres, err := client.BankQueryClient.Balance(context.Background(), &query)  \n

    Init client with key manager, for signing and sending tx

    keyManager, _ := keys.NewPrivateKeyManager(\"ab463aca3d2965233da3d1d6108aa521274c5ddc2369ff72970a52a451863fbf\")\ngnfdClient := NewGreenfieldClient(\"localhost:9090\", \n                                \"greenfield_9000-121\",\n                                WithKeyManager(km),\n                                    WithGrpcDialOption(grpc.WithTransportCredentials(insecure.NewCredentials()))\n)\n
    "},{"location":"bnb-greenfield/for-developers/interact-node/#using-the-rest-endpoints","title":"Using the REST Endpoints","text":"

    As described in the gRPC guide, all gRPC services on the Cosmos SDK are made available for more convenient REST-based queries. The format of the URL path is based on the Protobuf service method\u2019s full-qualified name, but may contain small customizations so that final URLs look more idiomatic. For example, the REST endpoint for the cosmos.bank.v1beta1.Query/AllBalances method is GET /cosmos/bank/v1beta1/balances/{address}. Request arguments are passed as query parameters.

    As a concrete example, the curl command to make balances request is:

    curl \\\n    -X GET \\\n    -H \"Content-Type: application/json\" \\\n    http://localhost:1317/cosmos/bank/v1beta1/balances/$MY_VALIDATOR\n

    Make sure to replace localhost:1317 with the REST endpoint of your node, configured under the api.address field.

    The list of all available REST endpoints is available as a Swagger specification file, it can be viewed at localhost:1317/swagger. Make sure that the api.swagger field is set to true in your app.toml.

    "},{"location":"bnb-greenfield/for-developers/interact-node/#query-for-historical-state-using-rest","title":"Query for historical state using REST","text":"

    Querying for historical state is done using the HTTP header x-cosmos-block-height. For example, a curl command would look like:

    curl \\\n    -X GET \\\n    -H \"Content-Type: application/json\" \\\n    -H \"x-cosmos-block-height: 279256\"\n    http://localhost:1317/cosmos/bank/v1beta1/balances/$MY_VALIDATOR\n

    Assuming the state at that block has not yet been pruned by the node, this query should return a non-empty response.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/","title":"APIs and SDKs - BNB Greenfield API and SDK","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/#apis-sdks","title":"APIs & SDKs","text":"

    Below are the lists of Official APIs and SDKs for BNB Greenfield in different languages.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/#official-apis","title":"Official APIs","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/#official-sdks","title":"Official SDKs","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/","title":"Go SDK Example - BNB Greenfield SDK","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#quickstart","title":"Quickstart","text":"

    The Greenfield SDK for Go provides APIs and utilities that developers can use to build Go applications that use Greenfield services, such as data storage and permission management.

    The SDK simplifies the process of programming directly with a web service interface. It takes care of many underlying details, including authentication, retrying requests, and managing errors.

    This guide provides configuration information, sample code, and an introduction to the SDK utilities.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#install","title":"Install","text":"

    The Greenfield SDK for Go requires Go 1.20 or later.You can view your current version of Go by running the go version command. For information about installing or upgrading your version of Go, see https://golang.org/doc/install.

    To install the SDK and its dependencies, run the following Go command.

    $ go get github.com/bnb-chain/greenfield-go-sdk\n

    Edit go.mod to replace dependencies

    replace (\n    cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9\n    cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9\n    github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2\n    github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1\n    github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3\n    github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1\n    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7\n)\n

    Install dependensies

    go mod tidy\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#usage","title":"Usage","text":"

    Now we\u2019re ready to connect to Greenfield testnet and interact with the Greenfield APIs. Let\u2019s write a simple script to query the Greenfield version to verify if everything works as expected.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#create-client","title":"Create client","text":"

    Create a main.go file in your project and add the following code.

    package main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/bnb-chain/greenfield-go-sdk/client\"\n    \"github.com/bnb-chain/greenfield-go-sdk/types\"\n)\n\nconst (\n    privateKey  = \"\"\n\n    // Mainnet Info\n    rpcAddr     = \"https://greenfield-chain.bnbchain.org:443\"\n    chainId     = \"greenfield_1017-1\"\n\n    // Testnet Info\n    // rpcAddr     = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n    // chainId     = \"greenfield_5600-1\"\n\n)\n\nfunc main() {\n    // import acccount\n    account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n    if err != nil {\n        log.Fatalf(\"New account from private key error, %v\", err)\n    }\n\n    // create client\n    cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n    }\n    ctx := context.Background()\n\n    // get node info from RPC\n    nodeInfo, versionInfo, err := cli.GetNodeInfo(ctx)\n    if err != nil {\n        log.Fatalf(\"unable to get node info, %v\", err)\n    }\n    log.Printf(\"nodeInfo moniker: %s, go version: %s\", nodeInfo.Moniker, versionInfo.GoVersion)\n\n    // query latest block height\n    height, err := cli.GetLatestBlockHeight(ctx)\n    if err != nil {\n        log.Fatalf(\"unable to get latest block height, %v\", err)\n    }\n\n    log.Printf(\"Current block height: %d\", height)\n}\n

    Run the following command in your project directory:

    go run main.go\n

    This will output something like:

    2023/06/22 10:44:16 nodeInfo moniker: validator-a, go version: go version go1.20.4 linux/amd64\n2023/06/22 10:44:16 Current block height: 817082\n

    If everything is set up correctly, your code will be able to connect to the Greenfield node and return the chain data as shown above.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#queries","title":"Queries","text":"

    In the previous step, we created a main.go file to demonstrate the basic steps to connect to the node and initialize a Client to query chain data. Next, let\u2019s use some more functions.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#1-get-current-chain-head","title":"1. Get Current Chain Head","text":"

    We can add the following code inmain.goto query current head of the chain.

      // query latest block height\n  blockByHeight, err := cli.GetBlockByHeight(ctx,height)\n    if err != nil {\n        log.Fatalf(\"unable to get block by height, %v\", err)\n    }\n    log.Printf(\"Current block height: %d\", blockByHeight.GetHeader())\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#2-get-address-balance","title":"2. Get Address Balance","text":"

    With a given greenfield wallet address, you can query its balance by calling GetAccountBalance function.

        // query current balance\n    balance, err := cli.GetAccountBalance(ctx, account.GetAddress().String())\n    if err != nil {\n        log.Fatalf(\"unable to get balance, %v\", err)\n    }\n    log.Printf(\"%s Current balance: %s\", account.GetAddress().String(), balance.String())\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#3-query-storage-providers","title":"3. Query Storage Providers","text":"

    In addition, the SDK provides support for querying the list of storage providers available and offers generic search capabilities for exploring metadata attributes.

        cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n    }\n    ctx := context.Background()\n\n    // get storage providers list\n    spLists, err := cli.ListStorageProviders(ctx, true)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n    }\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#4-query-storage-price","title":"4. Query Storage Price","text":"
        // choose the first sp to be the primary SP\n    primarySP := spLists[0].GetOperatorAddress()\n\n    // query price for storing data\n    price, err := cli.GetStoragePrice(ctx,primarySP)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n    }\n\n    log.Printf(\"Read Price is %s and Store price is %s \\n\",price.ReadPrice,price.StorePrice)\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#5-query-buckets","title":"5. Query Buckets","text":"

    You can query the bucket info like this:

        // head bucket\n    bucketInfo, err := cli.HeadBucket(ctx, bucketName)\n    handleErr(err, \"HeadBucket\")\n    log.Println(\"bucket info:\", bucketInfo.String())\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#5-query-objects","title":"5. Query Objects","text":"

    List all the objects under the same bucket

        // list object\n    objects, err := cli.ListObjects(ctx, bucketName, types.ListObjectsOptions{\n        ShowRemovedObject: false, Delimiter: \"\", MaxKeys: 100, EndPointOptions: &types.EndPointOptions{\n            Endpoint:  httpsAddr, // sp endpoint\n            SPAddress: \"\",\n        }})\n    log.Println(\"list objects result:\")\n    for _, obj := range objects.Objects {\n        i := obj.ObjectInfo\n        log.Printf(\"object: %s, status: %s\\n\", i.ObjectName, i.ObjectStatus)\n    }\n

    Apart from the basic data queries shown above, there are many more features. Please see theJSON-RPC API Referencefor all Greenfield API definitions.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#transactions","title":"Transactions","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#1-manage-wallet","title":"1. Manage Wallet","text":"

    Greenfield wallets hold addresses that you can use to manage objects, sign transactions, and pay for gas fees. In this section, we will demonstrate different ways to manage your wallet.

        //import mnemonic\n    account, err := types.NewAccountFromMnemonic(\"test\", mnemonic)\n    //import private key\n    account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n

    Let\u2019s create a second wallet address so we can test transfers. The new address will be created locally and start with 0 token balance:

        //create a differet account\n    account2, _, err := types.NewAccount(\"test2\")\n

    Now, let\u2019s try to transfer tBNB to this new address. Under the hood, this will create a transaction to transfer tBNB fromfromAddresstotoAddress, sign the transaction using SDK, and send the signed transaction to the Greenfield node.

        // transfer token to acccount2\n    transferTxHash, err := cli.Transfer(ctx, account2.GetAddress().String(), math.NewIntFromUint64(1000000000000000000), types2.TxOption{})\n    if err != nil {\n        log.Fatalf(\"unable to send, %v\", err)\n    }\n    log.Printf(\"Transfer response: %s\", transferTxHash)\n\n    // wait for transaction hash\n    waitForTx, err := cli.WaitForTx(ctx, transferTxHash)\n\n    log.Printf(\"Wait for tx: %s\", waitForTx.String())\n\n    //verify account2's balance\n    balance, err = cli.GetAccountBalance(ctx, account2.GetAddress().String())\n

    Run the code to test the transfer of tBNB:

        go run account.go\n

    This will output something like:

    raw_log: '[{\"msg_index\":0,\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"/cosmos.bank.v1beta1.MsgSend\"},{\"key\":\"sender\",\"value\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"coin_spent\",\"attributes\":[{\"key\":\"spender\",\"value\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"},{\"key\":\"amount\",\"value\":\"1BNB\"}]},{\"type\":\"coin_received\",\"attributes\":[{\"key\":\"receiver\",\"value\":\"0x78C3A3d10B1032bB2810366361dCE84E2e92eFCB\"},{\"key\":\"amount\",\"value\":\"1BNB\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"0x78C3A3d10B1032bB2810366361dCE84E2e92eFCB\"},{\"key\":\"sender\",\"value\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"},{\"key\":\"amount\",\"value\":\"1BNB\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"}]}]}]'\ntimestamp: \"2023-06-22T20:02:19Z\"\ntx:\n  '@type': /cosmos.tx.v1beta1.Tx\n  auth_info:\n    fee:\n      amount:\n      - amount: \"6000000000000\"\n        denom: BNB\n      gas_limit: \"1200\"\n      granter: \"\"\n      payer: \"\"\n    signer_infos:\n    - mode_info:\n        single:\n          mode: SIGN_MODE_EIP_712\n      public_key:\n        '@type': /cosmos.crypto.eth.ethsecp256k1.PubKey\n        key: AirjhHwjRcZ34op5yCKHtDkn91RDgFOY8cJmbHH6Tmlu\n      sequence: \"12\"\n    tip: null\n  body:\n    extension_options: []\n    memo: \"\"\n    messages:\n    - '@type': /cosmos.bank.v1beta1.MsgSend\n      amount:\n      - amount: \"1\"\n        denom: BNB\n      from_address: 0x525482AB3922230e4D73079890dC905dCc3D37cd\n      to_address: 0x78C3A3d10B1032bB2810366361dCE84E2e92eFCB\n    non_critical_extension_options: []\n    timeout_height: \"0\"\n  signatures:\n  - FjUNT2dzpQZhCmVTLDGMEy1uR1NaNLeYjvqQiPr2xHM5xxeYP5Mic8CSxZtg3k4WHcAIEnQNcszqBi7fsgETagA=\ntxhash: DFC2CE0514FE334B5BCB6BC3EBCCCD7A6E16B4CAEDC4FFDBE3F2FA3B6E548E61\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#make-a-storage-deal","title":"Make A Storage Deal","text":"

    Storing data is one of the most important features of Greenfield. In this section, we\u2019ll walk through the end-to-end process of storing your data on the Greenfield network. We\u2019ll start by importing your data, then make a storage deal with a storage provider, and finally wait for the deal to complete.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#1-create-a-storagego-file","title":"1. Create a storage.go file","text":"

    Create a storage.go file in yourdemoproject and add the following boilerplate code:

    func main() {\n\n  // initialize account\n  account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n  log.Println(\"address info:\", account)\n\n  if err != nil {\n      log.Fatalf(\"New account from private key error, %v\", err)\n  }\n\n  //initialize client\n  cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n  if err != nil {\n      log.Fatalf(\"unable to new greenfield client, %v\", err)\n  }\n  ctx := context.Background()\n\n  // 1. choose storage provider\n\n  // 2. Create a bucket\n\n  // 3. Upload your data and set a quota\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#2-choose-sp","title":"2. Choose SP","text":"

    You can query the list of SP.

        // get storage providers list\n    spLists, err := cli.ListStorageProviders(ctx, true)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n    }\n    //choose the first sp to be the primary SP\n    primarySP := spLists[0].GetOperatorAddress()\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#3-create-buckets","title":"3. Create Buckets","text":"

    Bucket can be private or public. You can customize it with options.

        chargedQuota := uint64(100)\n    visibility := storageTypes.VISIBILITY_TYPE_PUBLIC_READ\n    opts := types.CreateBucketOptions{Visibility: visibility, ChargedQuota: chargedQuota}\n

    To understand how does quota work, read this.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#4-upload-objects","title":"4. Upload Objects","text":"

    Objects can also be private or public.

    Uploading objects is composed of two parts: create and put.

        // create and put object\n    txnHash, err := cli.CreateObject(ctx, bucketName, objectName, bytes.NewReader(buffer.Bytes()), types.CreateObjectOptions{})\n\n    handleErr(err, \"CreateObject\")\n\n    // Put your object\n    err = cli.PutObject(ctx, bucketName, objectName, int64(buffer.Len()),\n        bytes.NewReader(buffer.Bytes()), types.PutObjectOptions{TxnHash: txnHash})\n    handleErr(err, \"PutObject\")\n\n    log.Printf(\"object: %s has been uploaded to SP\\n\", objectName)\n\n    //wait for SP to seal your object\n    waitObjectSeal(cli, bucketName, objectName)\n

    The primary SP syncs with secondary SPs to set up the data redundancy, and then it signs a \u201cSeal\u201d transaction with the finalized metadata for storage. If the primary SP determines that it doesn\u2019t want to store the file due to whatever reason, it can also \u201cSealReject\u201d the request.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#object-management","title":"Object Management","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#1-read-object","title":"1. Read Object","text":"

    You can call GetObject function to download data.

        // get object\n    reader, info, err := cli.GetObject(ctx, bucketName, objectName, types.GetObjectOption{})\n    handleErr(err, \"GetObject\")\n    log.Printf(\"get object %s successfully, size %d \\n\", info.ObjectName, info.Size)\n    handleErr(err, \"GetObject\")\n    objectBytes, err := io.ReadAll(reader)\n    if !bytes.Equal(objectBytes, buffer.Bytes()) {\n        handleErr(errors.New(\"download content not same\"), \"GetObject\")\n    }\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#2-update-object-visibility","title":"2. Update Object Visibility","text":"

    You can call UpdateObjectVisibility to change object visibility

        // update object visibility\n    updateBucketTx, err := ccli.UpdateBucketVisibility(s.ClientContext, bucketName,\n    storageTypes.VISIBILITY_TYPE_PRIVATE, types.UpdateVisibilityOption{})\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#3-delete-object","title":"3. Delete Object","text":"

    The function DeleteObject support deleting objects.

        // delete object\n    delTx, err := cli.DeleteObject(ctx, bucketName, objectName, types.DeleteObjectOption{})\n    handleErr(err, \"DeleteObject\")\n    _, err = cli.WaitForTx(ctx, delTx)\n    if err != nil {\n        log.Fatalln(\"txn fail\")\n    }\n    log.Printf(\"object: %s has been deleted\\n\", objectName)\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#greenfield-client-documentation","title":"Greenfield Client Documentation","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#usage_1","title":"Usage","text":"

    Import Greenfield Go SDK client package, client package provides a client for interacting with Greenfield blockchain and SPs.

        import \"github.com/bnb-chain/greenfield-go-sdk/client\"\n

    Provide Greenfield blockchain RPC endpoint and chainID info, new a Greenfield Go SDK client instance to start the journey.

    func New(chainID string, endpoint string, option Option) (Client, error)\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#api-documentation","title":"API Documentation","text":"

    The Greenfield Go SDK client wraps lots of APIs for interacting with Greenfield, including account, bank, storage, and permission APIs, etc. For more details, you can refer to Greenfield Go SDK Docs.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#code-repository","title":"Code Repository","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-go/#more-info","title":"More info","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/","title":"Javascript SDK Example - BNB Greenfield SDK","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#quickstart","title":"Quickstart","text":"

    The BNB Greenfield JavaScript SDK is designed for front-end environments and provides an API for interacting with BNB Greenfield decentralized storage. It offers a range of operations, including retrieving permission details, gas fees, etc. The SDK also includes a crypto component for signing transactions and sending them to BNB Greenfield.

    However, it should be noted that this SDK does not include methods for interacting with BNB Smart Chain (BSC). For a comprehensive understanding of available operations, refer to the API Reference.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#install","title":"Install","text":"
    npm install @bnb-chain/greenfield-js-sdk\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#usage","title":"Usage","text":"

    To utilize the SDK functionality, users need to instantiate a client object from the SDK. This client object serves as the interface to interact with BNB Greenfield and perform the desired operations.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#create-client","title":"Create client","text":"
    import { Client } from '@bnb-chain/greenfield-js-sdk'\n\nexport const client = Client.create('https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org', '5600');\n

    The SDK offers two types of operations - sending transactions to BNB Greenfield, allowing users to modify the state of the blockchain; the second type enables users to send queries and retrieve metadata information about objects stored on the blockchain.

    The SDK consists of two parts:

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#transactions","title":"Transactions","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#1-transaction-construction","title":"1. Transaction construction","text":"

    The SDK offers functionality for transferring tokens between accounts, providing a straightforward and convenient way to perform token transfers. With the SDK, users can easily initiate and execute token transfers within the desired accounts, streamlining the process of managing and exchanging tokens.

    The SDK includes functionality for simulating and broadcasting transactions, allowing users to retrieve essential information related to gas fees, and sending the transaction over network.

    const { simulate, broadcast } = await client.account.transfer({\n  fromAddress: address,\n  toAddress: transferInfo.to,\n  amount: [\n    {\n      denom: 'BNB',\n      amount: ethers.utils.parseEther(transferInfo.amount).toString(),\n    },\n  ],\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#2-simulate-transactions","title":"2. Simulate Transactions","text":"

    This function returns the estimated gas limit, gas price, and overall gas fee.

    // simulate tx\nconst simulateInfo = await simulate({\n   denom: 'BNB',\n});\n

    Example output

    {\n   \"gasLimit\":2400,\n   \"gasPrice\":\"5000000000\",\n   \"gasFee\":\"0.000012\"\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#3-broadcast-transactions","title":"3. Broadcast Transactions","text":"

    Use the API endpoint to send the transaction data to the blockchain network.

    // broadcast tx\n// This includes details such as gas limit, gas price, and overall gas fee.\nconst broadcastRes = await broadcast({\n  denom: 'BNB',\n  gasLimit: Number(simulateInfo.gasLimit),\n  gasPrice: simulateInfo.gasPrice,\n  payer: address,\n  granter: '',\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#notice-signature-mode-for-broadcast","title":"NOTICE: Signature mode for Broadcast","text":"

    broadcast use window.ethereum as signature provider by default.

    If you want to use others, you can set signTypedDataCallback:

    // TrustWallet\nconst broadcastRes = await broadcast({\n  //...\n  signTypedDataCallback: async (addr: string, message: string) => {\n    return await window.trustwallet.request({\n      method: 'eth_signTypedData_v4',\n      params: [addr, message],\n    });\n  }\n});\n

    If you broadcast in Nodejs, you can broadcast a tx by privateKey:

    const broadcastRes = await broadcast({\n  //...\n  privateKey: '0x.......'\n});\n

    Example output after broadcast your transaction:

    transaction result
    {\n   \"code\":0,\n   \"height\":449276,\n   \"txIndex\":0,\n   \"events\":[\n      {\n         \"type\":\"coin_spent\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"coin_received\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"transfer\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"message\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"tx\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"tx\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"tx\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"message\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"coin_spent\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"coin_received\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"transfer\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"message\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"greenfield.payment.EventStreamRecordUpdate\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"greenfield.payment.EventStreamRecordUpdate\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"greenfield.payment.EventStreamRecordUpdate\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      },\n      {\n         \"type\":\"greenfield.storage.EventCreateBucket\",\n         \"attributes\":[\n            \"Array\"\n         ]\n      }\n   ],\n   \"rawLog\":\"..\",\n   \"transactionHash\":\"D304242145ED9B44F05431C3798B3273CF2A907E6AE1CA892759985C900D6E72\",\n   \"gasUsed\":2400,\n   \"gasWanted\":2400\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#4-multi-transactions","title":"4. Multi-Transactions","text":"

    The SDK also provides support for bundling multiple operations into a single transaction, thereby reducing gas fees. This feature allows users to optimize their transactions by combining several operations together, minimizing the overall gas cost associated with executing them individually. By leveraging this functionality, users can effectively manage their gas fees and enhance the efficiency of their transactions within the blockchain network using the SDK.

    const createGroupTx = await client.group.createGroup(params);\nconst mirrorGroupTx = await client.crosschain.mirrorGroup({\n   groupName,\n   id,\n   operator,\n});\n\nconst principal = {\n  type: PermissionTypes.PrincipalType.PRINCIPAL_TYPE_GNFD_GROUP,\n  value: GRNToString(newGroupGRN(address as string, groupName)),\n};\n\nconst statement: PermissionTypes.Statement = {\n  effect: PermissionTypes.Effect.EFFECT_ALLOW,\n  actions: [PermissionTypes.ActionType.ACTION_GET_OBJECT],\n  resources: [\n    GRNToString(\n      type === 'Data'\n        ? newObjectGRN(bucketName, name)\n        : newObjectGRN(bucketName, '*'),\n    ),\n  ],\n};\n\nconst policyTx = await client.object.putObjectPolicy(bucketName, name, {\n  operator: address,\n  statements: [statement],\n  principal,\n});\n\nconst { simulate, broadcast } = await multiTx([\n  createGroupTx,\n  mirrorGroupTx,\n  policyTx,\n]);\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#querying-metadata","title":"Querying Metadata","text":"
    const { client, selectSp, generateString } = require('./client');\nconst { ACCOUNT_ADDRESS, ACCOUNT_PRIVATEKEY } = require('./env');\nconst Long = require('long');\n\n(async () => {\n  // get account info\n  const addrInfo = await client.account.getAccount(ACCOUNT_ADDRESS);\n\n  console.log('address is', addrInfo);\n\n\n})\n

    Example output

    {\n   \"address\":\"0x525482AB3922230e4D73079890dC905dCc3D37cd\",\n   \"pubKey\":{\n      \"typeUrl\":\"/cosmos.crypto.eth.ethsecp256k1.PubKey\",\n      \"value\":\"CiECKuOEfCNFxnfiinnIIoe0OSf3VEOAU5jxwmZscfpOaW4=\"\n   },\n   \"accountNumber\":\"5012\",\n   \"sequence\":\"9\"\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#storage-provider-client","title":"Storage Provider Client","text":"

    https://github.com/bnb-chain/greenfield-storage-provider/tree/master/docs/storage-provider-rest-api

    In addition, the SDK provides support for querying the list of storage providers available and offers generic search capabilities for exploring metadata attributes.

    SDK support two authentication type:

    getBucketReadQuota as example:

    // generate seed:\nconst allSps = await getAllSps();\nconst offchainAuthRes = await client.offchainauth.genOffChainAuthKeyPairAndUpload(\n  {\n    sps: allSps,\n    chainId: GREEN_CHAIN_ID,\n    expirationMs: 5 * 24 * 60 * 60 * 1000,\n    domain: window.location.origin,\n    address: 'your address',\n  },\n  provider: 'wallet provider',\n);\n\n// request sp api\nconst bucketQuota = await client.bucket.getBucketReadQuota(\n  {\n    bucketName,\n  },\n  {\n    type: 'EDDSA',\n    seed: offchainAuthRes.seedString,\n    domain: window.location.origin,\n    address: 'your address',\n  },\n);\n
    // Node.js:\n// request sp api\nconst bucketQuota = await client.bucket.getBucketReadQuota(\n  {\n    bucketName,\n  },\n  {\n    type: 'ECDSA',\n    privateKey: '0x....'\n  },\n);\n

    Others functions:

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#list-storage-providers","title":"List Storage Providers","text":"
    export const getSps = async () => {\n  const sps = await client.sp.getStorageProviders();\n  const finalSps = (sps ?? []).filter(\n    (v: any) => v?.description?.moniker !== 'QATest',\n  );\n\n  return finalSps;\n};\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#search-for-objects","title":"Search for objects","text":"

    It\u2019s important to note that even if an object is set to private, its metadata remains publicly accessible. This metadata includes information such as file size, file type, and file name.

    export const searchKey = async (key: string) => {\n  try {\n    return await client.sp.listGroup(key, `${DAPP_NAME}_`, {\n      sourceType: 'SOURCE_TYPE_ORIGIN',\n      limit: 1000,\n      offset: 0,\n    });\n  } catch (e) {\n    return [];\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#examples","title":"Examples","text":"

    Now let\u2019s make a complete example, includes:

    1. create bucket
    2. create object and upload it to the bucket
    3. download the object
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#prepare","title":"Prepare","text":"

    To begin, create an account and deposit tokens into it on Greenfield. Follow the instructions provided in Token Transfer. Please be aware that if your account does not have any BNB, the transaction will not be executed.

    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#choose-storage-provider","title":"Choose Storage Provider","text":"

    Storing data is one of the most important features of Greenfield. All storage-related apis require the storage provider to be chose.

    select sp
    const spList = await client.sp.getStorageProviders();\nconst sp = {\n   operatorAddress: spList[0].operatorAddress,\n   endpoint: spList[0].endpoint,\n};\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#ecdsa-offchainauth","title":"ECDSA / OffChainAuth","text":"

    ECDSA require users to use private key for authentication.

    OffChainAuth is used to authenticate yourself to the provider.

    Code can\u2019t access user\u2019s private key on browser, so we use OffChainAuth on browser and use ECDSA on Nodejs.

    BrowserNodejs Browser
    // MetaMask\nconst provider = window.ethereum;\n\nconst offchainAuthRes = await client.offchainauth.genOffChainAuthKeyPairAndUpload({\n   sps: {\n      address: sp.operatorAddress,\n      endpoint: sp.endpoint,\n   },\n   chainId: '5600',\n   expirationMs: 5 * 24 * 60 * 60 * 1000,\n   domain: window.location.origin,\n   // your wallet account\n   address: '0x..',\n}, provider);\n

    Info

    Nodejs don\u2019t need offchainauth.

    Nodejs
    // your account\nconst ACCOUNT_ADDRESS = '0x....'\n\n// your account's private key\nconst ACCOUNT_PRIVATEKEY = '0x....'\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#1-create-bucket","title":"1. Create Bucket","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#11-construct-create-bucket-tx","title":"1.1 construct create bucket tx","text":"

    Bucket can be private or public, you can customize it with options (visibility):

    construct create bucket tx
    const createBucketTx = await client.bucket.createBucket(\n  {\n    bucketName: 'bucket_name',\n    creator: address,\n    visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,\n    chargedReadQuota: Long.fromString('0'),\n    primarySpAddress: sp.operatorAddress,\n    paymentAddress: address,\n  }\n);\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#12-simulate-create-bucket-tx","title":"1.2 simulate create bucket tx","text":"simulate create bucket tx
    const createBucketTxSimulateInfo = await createBucketTx.simulate({\n   denom: 'BNB',\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#13-broadcast-create-bucket-tx","title":"1.3 broadcast create bucket tx","text":"BrowserNodejs broadcast create bucket tx
    const res = await createBucketTx.broadcast({\n   denom: 'BNB',\n   gasLimit: Number(simulateInfo?.gasLimit),\n   gasPrice: simulateInfo?.gasPrice || '5000000000',\n   payer: address,\n   granter: '',\n});\n
    broadcast create bucket tx
    const res = await createBucketTx.broadcast({\n   denom: 'BNB',\n   gasLimit: Number(createBucketTxSimulateInfo?.gasLimit),\n   gasPrice: createBucketTxSimulateInfo?.gasPrice || '5000000000',\n   payer: ACCOUNT_ADDRESS,\n   granter: '',\n   // highlight-start\n   privateKey: ACCOUNT_PRIVATEKEY,\n   // highlight-end\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#2-create-object","title":"2. Create Object","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#21-construct-create-object-tx","title":"2.1 construct create object tx","text":"

    Like the visibility of bucket, object also has a visibility:

    Getting file\u2019s checksum need reed-solomon:

    BrowserNodejs
    import { ReedSolomon } from '@bnb-chain/reed-solomon';\n\nconst rs = new ReedSolomon();\n\n// file is File type\nconst fileBytes = await file.arrayBuffer();\nconst expectCheckSums = rs.encode(new Uint8Array(fileBytes));\n
    const fs = require('node:fs');\nconst { NodeAdapterReedSolomon } = require('@bnb-chain/reed-solomon/node.adapter');\n\nconst filePath = './CHANGELOG.md';\nconst fileBuffer = fs.readFileSync(filePath);\nconst rs = new NodeAdapterReedSolomon();\nconst expectCheckSums = await rs.encodeInWorker(__filename, Uint8Array.from(fileBuffer));\n
    const createObjectTx = await client.object.createObject(\n  {\n    bucketName: 'bucket_name',\n    objectName: 'object_name',\n    // user's account address\n    creator: '0x...',\n    visibility: VisibilityType.VISIBILITY_TYPE_PRIVATE,\n    contentType: 'json',\n    redundancyType: RedundancyType.REDUNDANCY_EC_TYPE,\n    payloadSize: Long.fromInt(13311),\n    expectChecksums: expectCheckSums.map((x) => bytesFromBase64(x)),\n  }\n);\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#22-simulate-create-object-tx","title":"2.2 simulate create object tx","text":"
    const createObjectTxSimulateInfo = await createObjectTx.simulate({\n   denom: 'BNB',\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#23-broadcast-create-object-tx","title":"2.3 broadcast create object tx","text":"BrowserNodejs
    const res = await createObjectTx.broadcast({\n   denom: 'BNB',\n   gasLimit: Number(simulateInfo?.gasLimit),\n   gasPrice: simulateInfo?.gasPrice || '5000000000',\n   payer: address,\n   granter: '',\n});\n
    const createObjectTxRes = await createObjectTx.broadcast({\n   denom: 'BNB',\n   gasLimit: Number(createObjectTxSimulateInfo?.gasLimit),\n   gasPrice: createObjectTxSimulateInfo?.gasPrice || '5000000000',\n   payer: ACCOUNT_ADDRESS,\n   granter: '',\n   // highlight-start\n   privateKey: ACCOUNT_PRIVATEKEY,\n   // highlight-end\n});\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#24-upload-object","title":"2.4 upload object","text":"BrowserNodejs
    const uploadRes = await client.object.uploadObject(\n   {\n      bucketName: createObjectInfo.bucketName,\n      objectName: createObjectInfo.objectName,\n      body: file,\n      txnHash: txHash,\n   },\n   // highlight-start\n   {\n      type: 'EDDSA',\n      domain: window.location.origin,\n      seed: offChainData.seedString,\n      address,\n   },\n   // highlight-end\n);\n
    const uploadRes = await client.object.uploadObject(\n   {\n      bucketName: bucketName,\n      objectName: objectName,\n      body: createFile(filePath),\n      txnHash: createObjectTxRes.transactionHash,\n   },\n   // highlight-start\n   {\n      type: 'ECDSA',\n      privateKey: ACCOUNT_PRIVATEKEY,\n   }\n   // highlight-end\n);\n\n// convert buffer to file\nfunction createFile(path) {\n  const stats = fs.statSync(path);\n  const fileSize = stats.size;\n\n  return {\n    name: path,\n    type: '',\n    size: fileSize,\n    content: fs.readFileSync(path),\n  }\n}\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#3-download-object","title":"3. Download Object","text":"BrowserNodejs
    const res = await client.object.downloadFile(\n   {\n      bucketName: 'bucket_name',\n      objectName: 'object_name',\n   },\n   // highlight-start\n   {\n      type: 'EDDSA',\n      address,\n      domain: window.location.origin,\n      seed: offChainData.seedString,\n   },\n   // highlight-end\n);\n
    const res = await client.object.getObject(\n   {\n      bucketName: 'bucket_name',\n      objectName: 'object_name',\n   },\n   // highlight-start\n   {\n      type: 'ECDSA',\n      privateKey: ACCOUNT_PRIVATEKEY,\n   }\n   // highlight-end\n);\n\n// res.body is Blob\nconsole.log('res', res)\nconst buffer = Buffer.from([res.body]);\nfs.writeFileSync('your_output_file', buffer)\n
    "},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#code-repository","title":"Code Repository","text":""},{"location":"bnb-greenfield/for-developers/apis-and-sdks/sdk-js/#api-documentation","title":"API Documentation","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/","title":"Contract Entrypoint - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#contract-entrypoint","title":"Contract Entrypoint","text":"

    Greenfield is based on a cross-chain programming model. It allows for the manipulation of data models on Greenfield via smart contracts on BSC or opBNB. These data models include objects, buckets, file permissions, and more. Below are the contract addresses deployed on various networks.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#bsc-mainnet","title":"BSC Mainnet","text":"

    DeployCommitId: c8e6a293b628f9063918ba8cd9c00ca41ded18db

    contract name address GovHub 0x1c9766EbcA1f38A06A04947129B394bF7FEc4599 CrossChain 0x77e719b714be09F70D484AB81F70D02B0E182f7d TokenHub 0xeA97dF87E6c7F68C9f95A69dA79E19B834823F25 LightClient 0x433bB48Bd86c089375e53b2E2873A9C4bC0e986B RelayerHub 0x31C477F05CE58bB81A9FB4b8c00560f1cBe185d1 BucketHub 0xE909754263572F71bc6aFAc837646A93f5818573 ObjectHub 0x634eB9c438b8378bbdd8D0e10970Ec88db0b4d0f GroupHub 0xDd9af4573D64324125fCa5Ce13407be79331B7F7 BucketERC721Token 0xC92d1d4b64Aebe28042206656b9E70E571A0E5eF ObjectERC721Token 0x4B92705a60d69f7A96aaDB8faa892526eB71adb7 GroupERC721Token 0x943FAC6CEBE6e45CE59bA911E5B6447c1a991450 MemberERC1155Token 0xAb73f243Be4d0fC5644c822351eC77e85DC2B5Ea PermissionHub 0xe1776006dBE9B60d9eA38C0dDb80b41f2657acE8 PermissionToken 0xE8d6aC02dB463c1463116c72A6164462B0660dEc MultiMessage 0x26204702935e2D617EE75B795152B9623a7d9809 GreenfieldExecutor 0xFa39D9111D927836b14D071d43e0aAD9cE83bBBf

    Extra:

    contract name address Deployer 0x4763c12b21a548BCbD22a682fb15930565e27C43 ProxyAdmin 0xf9010DC773eE3961418C96dc67Fc5DcCB3EA2C08

    For more details, you can refer to Greenfield Contracts Mainnet Deployment.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#bsc-testnet","title":"BSC Testnet","text":"

    DeployCommitId: 20cc1f5784a621438114847753cda289f3ed76fa

    contract name address GovHub 0xC8951B5DD89015DcD0606A63B23C8A67ae316302 CrossChain 0xa5B2c9194131A4E0BFaCbF9E5D6722c873159cb7 TokenHub 0xED8e5C546F84442219A5a987EE1D820698528E04 LightClient 0xa9249cefF9cBc9BAC0D9167b79123b6C7413F50a RelayerHub 0x91cA83d95c8454277d1C297F78082B589e6E4Ea3 BucketHub 0x5BB17A87D03620b313C39C24029C94cB5714814A ObjectHub 0x1b059D8481dEe299713F18601fB539D066553e39 GroupHub 0x50B3BF0d95a8dbA57B58C82dFDB5ff6747Cc1a9E BucketERC721Token 0xF6CB188D3346de442b171d015202e605B0697A2a ObjectERC721Token 0xc6a7192937961622D27956F412c4ce242F159311 GroupERC721Token 0x7fC61D6FCA8D6Ea811637bA58eaf6aB17d50c4d1 MemberERC1155Token 0x43bdF3d63e6318A2831FE1116cBA69afd0F05267 PermissionHub 0x25E1eeDb5CaBf288210B132321FBB2d90b4174ad PermissionToken 0xEBda3C285f79bEAF34416732F1F8Fa1e6B4B9dF7 MultiMessage 0x54be643072eB8cF38Ac0c57Abc72b9c0368C8699 GreenfieldExecutor 0x3E3180883308e8B4946C9a485F8d91F8b15dC48e

    Extra:

    contract name address Deployer 0x79aC4Ce73Cf5c4896a311CD39d2EB47E604D18E3 ProxyAdmin 0xdD1c0a54a9EDEa8d0821AEB5BE54c51B79fa4c2e

    For more details, you can refer to Greenfield Contracts Testnet Deployment.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#opbnb-testnet","title":"opBNB Testnet","text":"

    DeployCommitId: 6857ebfd2fd157c776cb8fc5f3dfb42696efeed2

    contract name address GovHub 0x64cB82CF53BE02fF56a3D5527beEF7302E740911 CrossChain 0xF0Bcf6E4F72bCB33b944275dd5c9d4540a259eB9 TokenHub 0x59614C9e9B5Df6dF4dc9e457cc7F3a67D796d3b2 LightClient 0xc50791892F6528E42A58DD07869726079C71F3f2 RelayerHub 0x59ACcF658CC4589C3C41720fd48e869B97A748a1 BucketHub 0xCAB5728B7cc21D0056E237D371b28efEEBFd8C2d ObjectHub 0xb23002c5C3DCe3312e190d9D186C4aB29F7cF26F GroupHub 0xe53725ac14bD77fA4754fC5a09889135C2c7Bc25 BucketERC721Token 0xCacc33C05ad335c929e62D87BB96D5c5E5A19641 ObjectERC721Token 0xb3e4d757b36A76fd968C97ed922Bd77AB2c72f62 GroupERC721Token 0x8C74F8e6cD4DCb307d344F358683594A68d66CD9 PermissionHub 0x089e97333da0B4260131068b7492D10fbEeC67BC PermissionToken 0x72705569ed3CC26dEC421f542191B8ac7F62c3e7 MultiMessage 0xc461eCE1922978d0336B03942cE70aCef4C5D09C GreenfieldExecutor 0x4bF975A172793FbcFff30Ffe5b3141A5C5aeBE52

    Extra:

    contract name address Deployer 0x84b3418faA3be4Bed168E2D00C7696b21008DcfD ProxyAdmin 0x9d067d0D30CA19bB24551c9b654B8b9BB83c8634

    For more details, you can refer to Greenfield Contracts Testnet Deployment.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/contract-list/#opbnb-mainnet","title":"opBNB Mainnet","text":"

    DeployCommitId: 6857ebfd2fd157c776cb8fc5f3dfb42696efeed2

    contract name address GovHub 0xCc63407862619bc65e5E09aFe521C6078C7fa730 CrossChain 0x7E376AEFAF05E20e3eB5Ee5c08fE1B9832b175cE TokenHub 0x723987D45BA424D562b087eE032b8C27F2E7b689 LightClient 0xf51ba131716776685A805E8E4Ecc95be2f923B93 RelayerHub 0xEd873b460C53D22f0FF3fc511854d9b8b16C4aE2 BucketHub 0xDbf8aEcB0F697A5c71baA0C1470Ba8D7f0395018 ObjectHub 0x8FcE352C1971cEa4c8b7b450C84780530713AcCd GroupHub 0x2968a07d24699F0Ffe1e17eCaebeF6BB50BCed68 BucketERC721Token 0x18C5f966795BC105B7F1bDf3313A540a0D62c22b ObjectERC721Token 0x9342750477676b257Cf28878320815dF94B78182 GroupERC721Token 0x488e054cc55Ba7a97e32B73122630364d4ffc050 MemberERC1155Token 0x9841F55651acd38019B8B895083F7B5f9933Ca44 PermissionHub 0x979876507F1395E5D391F9Dbef68468a22162B8D PermissionToken 0xb8AE22AA0B0F125B74D385261b26282a44224aCc MultiMessage 0x1aA380808eCef9BA5550fadaa97f2fD682B7f03A GreenfieldExecutor 0xdFc5DC31bfbf992C19C171db273A028736322Ec4

    Extra:

    contract name address Deployer 0xC6AA4CE979fbd263B8B32b9A162cA68F44D723a3 ProxyAdmin 0xD2e5D66A683d2dd67e8C9aAFb317Db96acfc3F00

    For more details, you can refer to Greenfield Contracts Mainnet Deployment.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/","title":"Integrating BSC Smart Contracts with Greenfield Projects - BNB Greenfield Cross Chain Integration","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#contract-sdk","title":"Contract SDK","text":"

    The Smart Contract SDK, designed to facilitate the development of community-driven projects. The SDK serves as an upper layer wrapper for the Greenfield-Contracts library, which implements the cross-chain communication functionality. By providing a user-friendly interface to the underlying interface, the SDK simplifies the development process and enables developers to create and manage a variety of greenfield resources, like bucket, group, and object on BSC through smart contract directly.

    The SDK is organized into four primary parts: BaseApp, BucketApp, ObjectApp, and GroupApp. These components serve as the building blocks for developers. The BaseApp serves as the foundation for the other three components, providing common functions required by the BucketApp, ObjectApp, and GroupApp.

    The BucketApp is responsible for managing bucket-related operations, while the ObjectApp handles object-related actions. The GroupApp, being the most complex of the four, is designed to handle group-related operations.

    Each of these components is equipped with unique functions and virtual functions that can be implemented to suit specific project needs.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#components","title":"Components","text":"
    1. BaseApp: Contains common functions used by the other components, as well as three virtual functions that need to be implemented for specific project requirements.
    2. BucketApp: A specialized module designed to handle bucket-related operations, such as creating and deleting buckets, and processing bucket resource calls.
    3. ObjectApp: A specialized module focused on object-related operations, specifically object deletion since creating objects from BSC is not supported.
    4. GroupApp: A more complex module that handles group-related operations, such as creating, deleting, and updating groups, and managing group resource calls.
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#baseapp","title":"BaseApp","text":"

    The BaseApp contains common functions that are shared by BucketApp, ObjectApp, and GroupApp. These functions are essential for setting up and managing the environment for cross-chain operations. The BaseApp provides the following core functions:

    1. _getTotalFee(): This function returns the total value required to send a cross-chain package.
    2. Setters: There are several setters available for configuring various aspects of the smart contract, such as:
    3. callbackGasLimit: Sets the gas limit for the callback function.
    4. failureHandleStrategy: Sets the strategy for handling failures during the execution of the smart contract.

    In addition to these functions, BaseApp provides three virtual functions:

    1. greenfieldCall(uint32 status, uint8 resourceType, uint8 operationType, uint256 resourceId, bytes calldata callbackData): This function is a callback hook designed to handle cross-chain response. It is a virtual function that needs to be implemented by developers to define custom behaviors for different types of resources and operation types. This function is triggered when a cross-chain operation is completed on greenfield side and return a package to bsc, allowing developers to execute specific actions or update states in response to the completion of an operation. If the developers don\u2019t need callback, this function(as well as other callback related functions) can be undefined.
    2. retryPackage(uint8 resourceType): This function handles the retry mechanism for a package, based on its resource type. Developers should implement this function to define the behavior when a package needs to be retried.
    3. skipPackage(uint8 resourceType): This function allows for skipping a package, based on its resource type. Developers should implement this function to define the behavior when a package needs to be skipped.

    By implementing these virtual functions, developers can customize the behavior of their smart contracts to meet their specific requirements. With the BaseApp component, developers have a solid foundation on which to build their smart contract applications using BucketApp, ObjectApp, and GroupApp.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#bucketapp","title":"BucketApp","text":"

    The BucketApp component is a specialized module designed to handle bucket-related operations in the smart contract SDK. This component offers a range of functions to create, delete, and manage buckets, as well as to route and handle various bucket resource operations. Below, we provide a detailed overview of the functions included in the BucketApp:

    1. _bucketGreenfieldCall(uint32 status, uint8 operationType, uint256 resourceId, bytes calldata callbackData): This function serves as a router for bucket resource callback. It processes and directs the call based on the provided parameters.
    2. _retryBucketPackage(): This function retries a failed bucket resource package.
    3. _skipBucketPackage(): This function skips a failed bucket resource package.
    4. _createBucket(address _creator, string memory _name, BucketStorage.BucketVisibilityType _visibility, address _paymentAddress, address _spAddress, uint256 _expireHeight, uint32 _globalVirtualGroupFamilyId, bytes calldata _sig, uint64 _chargedReadQuota): This function sends a create bucket cross-chain request to greenfield without a callback. It takes various parameters, such as creator, name, visibility type, charged read quota, service provider address, expire height, global virtual family id and signature.
    5. _createBucket(address _creator, string memory _name, BucketStorage.BucketVisibilityType _visibility, address _paymentAddress, address _spAddress, uint256 _expireHeight, uint32 _globalVirtualGroupFamilyId, bytes calldata _sig, uint64 _chargedReadQuota, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function sends a create bucket cross-chain request to greenfield with a callback. It takes the same parameters as the previous function, along with some additional parameters for the callback.
    6. _deleteBucket(uint256 _tokenId): This function sends a delete bucket cross-chain request to greenfield without a callback, using the provided token ID.
    7. _deleteBucket(uint256 _tokenId, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function sends a delete bucket cross-chain request to greenfield with a callback, using the provided token ID and callback data.

    In addition to these functions, the BucketApp provides two virtual functions:

    1. _createBucketCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers can implement this function to define the behavior for the create bucket callback. The function receives the status, token ID, and callback data as parameters.
    2. _deleteBucketCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers can implement this function to define the behavior for the delete bucket callback. The function receives the status, token ID, and callback data as parameters.

    By implementing these virtual functions, developers can tailor the BucketApp component to suit their specific bucket-related operations and handle the corresponding callbacks as needed.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#objectapp","title":"ObjectApp","text":"

    The ObjectApp component is a specialized module designed to handle object-related operations in the smart contract SDK. This component offers a range of functions to manage objects and process object resource operations. However, please note that creating objects from BSC is currently not supported. Below, we provide a detailed overview of the functions included in the ObjectApp:

    1. _objectGreenfieldCall(uint32 status, uint8 operationType, uint256 resourceId, bytes calldata callbackData): This function serves as a router for object resource callback. It processes and directs the call based on the provided parameters.
    2. _retryObjectPackage(): This function retries a failed object resource package.
    3. _skipObjectPackage(): This function skips a failed object resource package.
    4. _deleteObject(uint256 _tokenId): This function deletes an object using the provided token ID. As creating objects from BSC is not supported, the ObjectApp focuses on deletion operations.
    5. _deleteObject(uint256 _tokenId, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function deletes an object with a callback, using the provided token ID and callback data.

    In addition to these functions, the ObjectApp provides one virtual function:

    1. _deleteObjectCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers need to implement this function to define the behavior for the delete object callback. The function receives the status, token ID, and callback data as parameters.

    By implementing this virtual function, developers can customize the ObjectApp component to handle object deletion operations and manage the corresponding callbacks as needed.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#groupapp","title":"GroupApp","text":"

    The GroupApp component is a specialized module designed to handle group-related operations in the smart contract SDK. This component is more complex compared to the BucketApp and ObjectApp, as it offers a range of functions to create, delete, update, and manage groups. Below, we provide a detailed overview of the functions included in the GroupApp:

    1. _groupGreenfieldCall(uint32 status, uint8 operationType, uint256 resourceId, bytes calldata callbackData): This function serves as a router for group resource callback. It processes and directs the call based on the provided parameters.
    2. _retryGroupPackage(): This function retries a failed group resource package.
    3. _skipGroupPackage(): This function skips a failed group resource package.
    4. _createGroup(address _owner, string memory _groupName): This function creates a new group with the provided owner address and group name.
    5. _createGroup(address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData,, address _owner, string memory _groupName, uint256 _callbackGasLimit): This function creates a new group with a callback, using the provided owner address, group name, and callback data.
    6. _deleteGroup(uint256 _tokenId): This function deletes a group using the provided token ID.
    7. _deleteGroup(uint256 _tokenId, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function deletes a group with a callback, using the provided token ID and callback data.
    8. _updateGroup(address _owner, uint256 _tokenId, uint8 _opType, address[] memory _members, uint64[] memory _expiration): This function updates a group based on the provided owner address, token ID, operation type, and an array of member addresses.
    9. _updateGroup(address _owner, uint256 _tokenId, uint8 _opType, address[] memory _members, uint64[] memory _expiration, address _refundAddress, PackageQueue.FailureHandleStrategy _failureHandleStrategy, bytes memory _callbackData, uint256 _callbackGasLimit): This function updates a group with a callback, using the provided owner address, token ID, operation type, an array of member addresses, and callback data.

    In addition to these functions, the GroupApp provides three virtual functions:

    1. _createGroupCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers need to implement this function to define the behavior for the create group callback. The function receives the status, token ID, and callback data as parameters.
    2. _deleteGroupCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers need to implement this function to define the behavior for the delete group callback. The function receives the status, token ID, and callback data as parameters.
    3. _updateGroupCallback(uint32 _status, uint256 _tokenId, bytes memory _callbackData): Developers need to implement this function to define the behavior for the update group callback. The function receives the status, token ID, and callback data as parameters.

    By implementing these virtual functions, developers can customize the GroupApp component to suit their specific group-related operations and handle the corresponding callbacks as needed.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#integration-example","title":"Integration Example","text":"

    We will walk you through the process of creating a decentralized Ebook shop using the Contract SDK as an example.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#prerequisites","title":"Prerequisites","text":"

    Before starting, make sure you have the following tools installed:

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#installation","title":"Installation","text":"
    $ npm install @bnb-chain/greenfield-contracts-sdk\n

    Alternatively, you can obtain the contracts directly from the GitHub repository (bnb-chain/greenfield-contracts-sdk). When doing so, ensure that you specify the appropriate release.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/#steps","title":"Steps","text":"
    1. Import the desired contracts, for example in examples/ebook-shop.sol:
    pragma solidity ^0.8.0;\n\nimport \"@bnb-chain/greenfield-contracts-sdk/BucketApp.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/ObjectApp.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/GroupApp.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/interface/IERC1155.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/interface/IERC721NonTransferable.sol\";\nimport \"@bnb-chain/greenfield-contracts-sdk/interface/IERC1155NonTransferable.sol\";\n...\n\ncontract EbookShop is BucketApp, ObjectApp, GroupApp {\n ...\n}\n
    1. Define the initialize function. Initialize the global variables in the init function. You can use the internal init functions:

      function initialize(\n    address _crossChain,\n    address _bucketHub,\n    address _objectHub,\n    address _groupHub,\n    address _ebookToken,\n    address _paymentAddress,\n    uint256 _callbackGasLimit,\n    address _refundAddress,\n    uint8 _failureHandleStrategy,\n    ...\n) public initializer {\n    __base_app_init_unchained(_crossChain, _callbackGasLimit, _refundAddress, _failureHandleStrategy);\n    __bucket_app_init_unchained(_bucketHub);\n    __group_app_init_unchained(_groupHub);\n    __object_app_init_unchained(_objectHub);\n\n    ...\n}\n
    2. Define and override the greenfieldCall, retryPackage and skipPackage functions if your dApp needs callback. You can route calls with the help of the internal method:

      function greenfieldCall(\n    uint32 status,\n    uint8 resoureceType,\n    uint8 operationType,\n    uint256 resourceId,\n    bytes calldata callbackData\n) external override(BucketApp, ObjectApp, GroupApp) {\n    require(msg.sender == crossChain, string.concat(\"EbookShop: \", ERROR_INVALID_CALLER));\n\n    if (resoureceType == RESOURCE_BUCKET) {\n        _bucketGreenfieldCall(status, operationType, resourceId, callbackData);\n    } else if (resoureceType == RESOURCE_OBJECT) {\n        _objectGreenfieldCall(status, operationType, resourceId, callbackData);\n    } else if (resoureceType == RESOURCE_GROUP) {\n        _groupGreenfieldCall(status, operationType, resourceId, callbackData);\n    } else {\n        revert(string.concat(\"EbookShop: \", ERROR_INVALID_RESOURCE));\n    }\n}\n\nfunction retryPackage(uint8 resoureceType) external override onlyOperator {\n    if (resoureceType == RESOURCE_BUCKET) {\n        _retryBucketPackage();\n    } else if (resoureceType == RESOURCE_OBJECT) {\n        _retryObjectPackage();\n    } else if (resoureceType == RESOURCE_GROUP) {\n        _retryGroupPackage();\n    } else {\n        revert(string.concat(\"EbookShop: \", ERROR_INVALID_RESOURCE));\n    }\n}\n\nfunction skipPackage(uint8 resoureceType) external override onlyOperator {\n    if (resoureceType == RESOURCE_BUCKET) {\n        _skipBucketPackage();\n    } else if (resoureceType == RESOURCE_OBJECT) {\n        _skipObjectPackage();\n    } else if (resoureceType == RESOURCE_GROUP) {\n        _skipGroupPackage();\n    } else {\n        revert(string.concat(\"EbookShop: \", ERROR_INVALID_RESOURCE));\n    }\n}\n
    3. Next you need to define the main functional parts of the app. You can send cross-chain request to system contracts with the help of internal functions like below:

      /**\n * @dev Create a new series.\n * \n * Assuming the sp provider's info will be provided by the front-end.\n */\nfunction createSeries(\n    string calldata name,\n    BucketStorage.BucketVisibilityType visibility,\n    uint64 chargedReadQuota,\n    address spAddress,\n    uint256 expireHeight,\n    bytes calldata sig\n) external payable {\n    require(bytes(name).length > 0, string.concat(\"EbookShop: \", ERROR_INVALID_NAME));\n    require(seriesId[name] == 0, string.concat(\"EbookShop: \", ERROR_RESOURCE_EXISTED));\n\n    bytes memory _callbackData = bytes(name); // use name as callback data\n    _createBucket(msg.sender, name, visibility, chargedReadQuota, spAddress, expireHeight, sig, _callbackData); // send cross-chain request\n}\n\n/**\n * @dev Provide an ebook's ID to publish it.\n *\n * An ERC1155 token will be minted to the owner.\n * Other users can buy the ebook by calling `buyEbook` function with given price.\n */\nfunction publishEbook(uint256 _ebookId, uint256 price) external {\n    require(\n        IERC721NonTransferable(objectToken).ownerOf(_ebookId) == msg.sender,\n        string.concat(\"EbookShop: \", ERROR_INVALID_CALLER)\n    );\n    require(ebookGroup[_ebookId] != 0, string.concat(\"EbookShop: \", ERROR_GROUP_NOT_EXISTED));\n    require(price > 0, string.concat(\"EbookShop: \", ERROR_INVALID_PRICE));\n\n    ebookPrice[_ebookId] = price;\n    IERC1155(ebookToken).mint(msg.sender, _ebookId, 1, \"\");\n}\n\n/**\n * @dev Provide an ebook's ID to buy it.\n *\n * Buyer will be added to the group of the ebook.\n * An ERC1155 token will be minted to the buyer.\n */\nfunction buyEbook(uint256 _ebookId) external payable {\n    require(ebookPrice[_ebookId] > 0, string.concat(\"EbookShop: \", ERROR_EBOOK_NOT_ONSHELF));\n\n    uint256 price = ebookPrice[_ebookId];\n    require(msg.value >= price, string.concat(\"EbookShop: \", ERROR_NOT_ENOUGH_VALUE));\n\n    IERC1155(ebookToken).mint(msg.sender, _ebookId, 1, \"\");\n\n    uint256 _groupId = ebookGroup[_ebookId];\n    address _owner = IERC721NonTransferable(groupToken).ownerOf(_groupId);\n    address[] memory _member = new address[](1);\n    _member[0] = msg.sender;\n    _updateGroup(_owner, _groupId, UPDATE_ADD, _member);\n}\n\n/**\n * @dev Provide an ebook's ID to downshelf it.\n *\n * The ebook will be removed from the shelf and cannot be bought.\n * Those who have already purchased are not affected.\n */\nfunction downshelfEbook(uint256 _ebookId) external {\n    require(\n        IERC721NonTransferable(objectToken).ownerOf(_ebookId) == msg.sender,\n        string.concat(\"EbookShop: \", ERROR_INVALID_CALLER)\n    );\n    require(ebookPrice[_ebookId] > 0, string.concat(\"EbookShop: \", ERROR_EBOOK_NOT_ONSHELF));\n\n    ebookPrice[_ebookId] = 0;\n}\n...\n
    4. Besides, you may need to provide a function for user to register their own resource that were created at greenfield side and then mirrored to BSC manually:

      /**\n * @dev Register bucket resource that mirrored from GreenField to BSC.\n */\nfunction registerSeries(string calldata name, uint256 tokenId) external {\n    require(\n        IERC721NonTransferable(bucketToken).ownerOf(tokenId) == msg.sender,\n        string.concat(\"EbookShop: \", ERROR_INVALID_CALLER)\n    );\n    require(bytes(name).length > 0, string.concat(\"EbookShop: \", ERROR_INVALID_NAME));\n    require(seriesId[name] == 0, string.concat(\"EbookShop: \", ERROR_RESOURCE_EXISTED));\n\n    seriesName[tokenId] = name;\n    seriesId[name] = tokenId;\n}\n...\n
    5. Define other view functions, internal functions and access control system according to your own needs.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/","title":"Contract as Bucket Owner - BNB Greenfield Demo","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#greenfield-demo-contract-as-bucket-owner","title":"Greenfield Demo: Contract as Bucket Owner","text":"

    BNB Greenfield provides the ability for a contract to manage buckets through greenfield cross-chain transactions, and we\u2019ll use a demo to briefly demonstrate the process.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#greenfield-demo-contract","title":"Greenfield Demo Contract","text":"

    The Demo includes the following parts:

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#greenfield-contracts-constant","title":"greenfield contracts constant:","text":"
        // BSC testnet\n    address public constant TOKEN_HUB = 0xED8e5C546F84442219A5a987EE1D820698528E04;\n    address public constant CROSS_CHAIN = 0xa5B2c9194131A4E0BFaCbF9E5D6722c873159cb7;\n    address public constant BUCKET_HUB = 0x5BB17A87D03620b313C39C24029C94cB5714814A;\n    address public constant PERMISSION_HUB = 0x25E1eeDb5CaBf288210B132321FBB2d90b4174ad;\n    address public constant SP_ADDRESS_TESTNET = 0x5FFf5A6c94b182fB965B40C7B9F30199b969eD2f;\n    address public constant GREENFIELD_EXECUTOR = 0x3E3180883308e8B4946C9a485F8d91F8b15dC48e;\n
    The addresses of Greenfield contracts deployed on the BSC testnet are available and configured here. You can find contracts deployed on other networks contract entrypoint"},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#create-bucket-and-set-bucket-flow-rate-limit","title":"create bucket and set bucket flow rate limit","text":"
        function createBucket(string memory bucketName, uint256 transferOutAmount, bytes memory _executorData) external payable;\n
    Provides the bucket name, initial BNB amount transferred to the demo contract on Greenfield and the executor data to set bucket flow rate limit.This API will create a new bucket owned by the smart contract and set the payment for it."},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#create-policy-to-allow-eoa-account-to-upload-files-to-the-bucket","title":"create policy to allow eoa account to upload files to the bucket","text":"
        function createPolicy(bytes memory createPolicyData) external payable;\n
    Construct the createPolicyData parameters to grant permission to the dedicated principle for the created bucket owned by the smart contract."},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#interact-script","title":"Interact Script","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#installation","title":"Installation","text":"
    git clone https://github.com/bnb-chain/greenfield-contracts.git\ncd greenfield-contracts && git checkout develop\nnpm install\nnpx hardhat compile\n\ncp .env.example .env\n# set `DeployerPrivateKey` on .env\n# make sure the tBNB balance of the account >= 0.5 BNB on BSC Testnet\nnpx hardhat run scripts/11-demo-contract-approve-eoa-upload.ts  --network bsc-testnet\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#workflow","title":"Workflow","text":"

    The interact script includes 4 steps as follows:

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#deploy-demo-contract","title":"deploy demo contract","text":"
        const demo = (await deployContract(operator, 'GreenfieldDemo')) as GreenfieldDemo;\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#create-bucket-whose-owner-is-the-demo-contract","title":"create bucket whose owner is the demo contract","text":"

    set bucket flow rate limit and cross-chain transfer 0.1 BNB to demo contract

    const bucketName = 'test-' + demo.address.substring(2, 6).toLowerCase();\n// - transferOutAmt: 0.1 BNB to demo contract on Greenfield\n// - set bucket flow rate limit to this bucket\n// - create bucket: 'test-approve-eoa-upload', its owner is demo contract\nconst dataSetBucketFlowRateLimit = ExecutorMsg.getSetBucketFlowRateLimitParams({\n    bucketName,\n    bucketOwner: demo.address,\n    operator: demo.address,\n    paymentAddress: demo.address,\n    flowRateLimit: '1000000000000000000',\n});\nconst executorData = dataSetBucketFlowRateLimit[1];\nconst transferOutAmt = ethers.utils.parseEther('0.1');\nconst value = transferOutAmt.add(relayFee.mul(3).add(ackRelayFee.mul(2)));\n\nlog('- transfer out to demo contract on greenfield', toHuman(transferOutAmt));\nlog('- create bucket', bucketName);\nlog('send crosschain tx!');\nconst receipt = await waitTx(\n    demo.createBucket(bucketName, transferOutAmt, executorData, { value })\n);\nlog(`https://testnet.bscscan.com/tx/${receipt.transactionHash}`);\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#get-bucket-id-by-name-after-bucket-created","title":"get bucket id by name after bucket created","text":"
    const bucketInfo = await client.bucket.getBucketMeta({ bucketName });\nconst bucketId = bucketInfo.body!.GfSpGetBucketMetaResponse.Bucket.BucketInfo.Id;\nlog('bucket created, bucket id', bucketId);\nconst hexBucketId = `0x000000000000000000000000000000000000000000000000000000000000${BigInt(\n    bucketId\n).toString(16)}`;\nlog(`https://testnet.greenfieldscan.com/bucket/${hexBucketId}`);\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/#create-policy-to-allow-eoa-account-upload-files-to-the-bucket-through-cross-chain-transaction","title":"create policy to allow EOA account upload files to the bucket through cross-chain transaction","text":"
    const uploaderEoaAccount = operator.address; // TODO set your eoa account to upload files\nlog('try to set uploader(eoa account) is', uploaderEoaAccount);\n\nconst policyDataToAllowUserOperateBucket = Policy.encode({\n    id: '0',\n    resourceId: bucketId, // bucket id\n    resourceType: ResourceType.RESOURCE_TYPE_BUCKET,\n    statements: [\n        {\n            effect: Effect.EFFECT_ALLOW,\n            actions: [ActionType.ACTION_CREATE_OBJECT], // allow upload file to the bucket\n            resources: [],\n        },\n    ],\n    principal: {\n        type: PrincipalType.PRINCIPAL_TYPE_GNFD_ACCOUNT,\n        value: uploaderEoaAccount,\n    },\n}).finish();\n\nawait waitTx(\n    demo.createPolicy(policyDataToAllowUserOperateBucket, { value: relayFee.add(ackRelayFee) })\n);\n

    Now the deployer account can upload files to the bucket on Greenfield.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/","title":"EVM Programmability - BNB Greenfield Cross Chain","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#evm-programmability","title":"EVM Programmability","text":"

    This document give a detailed introduction of cross-chain primitives that have been defined on EVM-compatible chains to enable developers to manage greenfield resources on the EVM-compatible chains directly.

    The Greenfield-Contracts Repo is the underlying backbone of the cross chain communication protocol. It is responsible for implementing the core cross-chain communication functionality that enables seamless interaction between Greenfield and EVM-compatible chains, like BSC and opBNB. The library handles the complexities of cross-chain operations, ensuring secure and efficient communication.

    During the development process, developers are most likely to interact with the following contracts: CrossChain, BucketHub, ObjectHub, GroupHub, PermissionHub, MultiMessage and GreenfieldExecutor.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#quick-glance","title":"Quick Glance","text":"Contract name Usage GovHub Handle system governance request CrossChain Handle cross-chain package TokenHub Transfer BNB from BSC to Greenfield LightClient Verify cross-chain package and sync light block RelayerHub Relayers could claim rewards from RelayerHub BucketHub Create/delete bucket ObjectHub Delete object GroupHub Create/delete group, update group member BucketERC721Token ERC721 token address representing buckets ownership ObjectERC721Token ERC721 token address representing objects ownership GroupERC721Token ERC721 token address representing groups ownership MemberERC1155Token ERC71155 token address representing the identity of group members PermissionHub The user can use Resource-Based Policy to grant permissions to other accounts. Any resources, such as buckets, objects and groups, can associate several policy. Only the resource owner can put a policy which associate to a resource he owned. 1. A policy associate to a bucket can allow grantee to operate the bucket or the specific objects. 2. A policy associate to a object/group can only allow to operator the object/group. PermissionToken ERC721 token address representing resource policy MultiMessage MultiMessage provides aggregation capabilities to support the atomicity of composite operations. GreenfieldExecutor Most native operations can be achieved by GreenfieldExecutor, like create payment account, deposit to payment account, withdraw from payment account, migrate bucket, cancel migrate bucket, update bucket info, toggle SP as delegated agent, set bucket flow ratelimit, copy object, update object info, set tag.

    Refer to the contract list for detailed contract address on different network.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#callback-handling","title":"CallBack Handling","text":"

    dApps on EVM-compatible chains, i.e. smart contracts on BSC, are allowed to implement their own logic to handle ACK and FAIL_ACK packages. The smart contracts can register callback functions to handle the ACK packages. To avoid consuming too much gas in callbacks, a gas limitation estimation should be done by the smart contracts that register the callbacks.

    Errors and failures can occur during cross-chain communication. dApps on EVM-compatible chains can handle these by retrying the package with a higher gas limit, skipping the package to tolerate failure, or upgrading their contract to handle corner cases.

    The following are the interfaces for dapps to handle failures:

     // retry the first failed package in the queue\n function retryPackage() external;\n // skip the first failed package in the queue\n function skipPackage() external;\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#permission-programmability","title":"Permission Programmability","text":"

    Whether resources are created on BSC or mapped from Greenfield to BSC, such as Buckets, Objects, and Groups, by default, only the owner account of these resources can manage them. However, with proper authorization, other accounts or contracts can be allowed to operate on the owner\u2019s resources. We provide two methods of authorization:

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#role-based-authorization","title":"Role-based authorization","text":"

    BucketHub, ObjectHub, and GroupHub all implement the following interface. Through the grant interface, other accounts can be granted the permission to create, delete, and update this type of resource for a certain period. This permission can also be revoked through the revoke interface.

    function grant(address account, uint32 acCode, uint256 expireTime) external {\n ...\n}\nfunction revoke(address account, uint32 acCode) external {\n    ...\n}\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#nft-token-authorization","title":"NFT token authorization","text":"

    Since BucketHub and ObjectHub implement the NFT721 standard, and GroupHub implements the ERC1155 standard, we use approve and setApprovalForAll to authorize specific resource Token IDs without restricting the types of operations, meaning both deletion and updating are allowed.

    function approve(address to, uint256 tokenId) public virtual {\n    ...\n}\nfunction setApprovalForAll(address operator, bool approved) public virtual {\n    ...\n}\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/interface/#detailed-interface","title":"Detailed Interface","text":"

    They provide the following interfaces respectively:

    IGroupHub

    The GroupHub contract provides the following interfaces to manage Group on BSC/opBNB directly.

    interface IGroupHub {\n    /** \n     * @dev  Query the contract address of group NFT.\n     * @return The contract address of group token.\n     * Each group will be mapped as a NFT on BSC.\n     * Group ID and NFT token ID are the same.\n     */\n    function ERC721Token() external view returns (address);\n    /** \n     * @dev  Query the contract address of member NFT.\n     * @return The contract address of member token.\n     * The member inside a group  will be mapped as a ERC1155 token on BSC.\n     * The ID of the ERC1155 token is same with the group ID.\n     */\n    function ERC1155Token() external view returns (address);\n\n    /**\n     * @dev create a group and send cross-chain request from BSC to GNFD.\n     *\n     * @param creator The group's owner.\n     * @param name The group's name.\n     */\n    function createGroup(address creator, string memory name) external payable returns (bool);\n\n    /**\n     * @dev create a group and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param creator The group's owner.\n     * @param name The group's name.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function createGroup(\n        address creator,\n        string memory name,\n        uint256 callbackGasLimit,\n        CmnStorage.ExtraData memory extraData\n    ) external payable returns (bool);\n\n    /**\n     * @dev delete a group and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The group's id.\n     */\n    function deleteGroup(uint256 id) external payable returns (bool);\n\n    /**\n     * @dev delete a group and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param id The group's id.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function deleteGroup(uint256 id, uint256 callbackGasLimit, CmnStorage.ExtraData memory extraData) external payable returns (bool);\n\n    /**\n     * @dev update a group's member and send cross-chain request from BSC to GNFD.\n     *\n     * @param synPkg Package containing information of the group to be updated.\n     */\n    function updateGroup(GroupStorage.UpdateGroupSynPackage memory synPkg) external payable returns (bool);\n\n    /**\n     * @dev update a group's member and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param synPkg Package containing information of the group to be updated.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function updateGroup(\n        GroupStorage.UpdateGroupSynPackage memory synPkg,\n        uint256 callbackGasLimit,\n        CmnStorage.ExtraData memory extraData\n    ) external payable returns (bool);\n\n    /**\n     * @dev Prepare the create group cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param owner The group's owner.\n     * @param name The group's name.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreateGroup(\n        address sender,\n        address owner,\n        string memory name\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete group cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The group's id.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteGroup(\n        address sender,\n        uint256 id\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the update group cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param synPkg Package containing information of the group to be updated.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareUpdateGroup(\n        address sender,\n        GroupStorage.UpdateGroupSynPackage memory synPkg\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n}\n

    IBucketHub

    The BucketHub contract provides the following interfaces to manage bucket on EVM-compatible chains, like BSC and opBNB, directly.

    interface IBucketHub {\n    /** \n     * @dev  Query the contract address of bucket NFT.\n     * @return The contract address of bucket token.\n     * Each bucket will be mapped as a NFT on BSC.\n     * Bucket ID and NFT token ID are the same.\n     */\n    function ERC721Token() external view returns (address);\n\n    /**\n     * @dev create a bucket and send cross-chain request from BSC to GNFD\n     *\n     * @param synPkg Package containing information of the bucket to be created\n     */\n    function createBucket(BucketStorage.CreateBucketSynPackage memory synPkg) external payable returns (bool);\n\n    /**\n     * @dev create a bucket and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param synPkg Package containing information of the bucket to be created.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function createBucket(\n        BucketStorage.CreateBucketSynPackage memory synPkg,\n        uint256 callbackGasLimit,\n        CmnStorage.ExtraData memory extraData\n    ) external payable returns (bool);\n\n    /**\n     * @dev delete a bucket and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The bucket's id.\n     */\n    function deleteBucket(uint256 id) external payable returns (bool);\n\n    /**\n     * @dev delete a bucket and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param id The bucket's id.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function deleteBucket(uint256 id, uint256 callbackGasLimit, CmnStorage.ExtraData memory extraData) external payable returns (bool);\n\n    /**\n     * @dev Prepare the create bucket cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param synPkg Package containing information of the bucket to be created.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreateBucket(\n        address sender,\n        CreateBucketSynPackage memory synPkg\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the create bucket cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param synPkg Package containing information of the bucket to be created.\n     * @param callbackGasLimit The gas limit for callback function\n     * @param extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreateBucket(\n        address sender,\n        CreateBucketSynPackage memory synPkg, \n        uint256 callbackGasLimit,\n        CmnStorage.ExtraData memory extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete bucket cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The bucket's id.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteBucket(\n        address sender,\n        uint256 id\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete bucket cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The bucket's id.\n     * @param callbackGasLimit The gas limit for callback function\n     * @param extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteBucket(\n        address sender,\n        uint256 id,\n        uint256 callbackGasLimit,\n        ExtraData memory extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n}\n

    IObjectHub

    The ObjectHub contract provides the following interfaces to manage object on EVM-compatible chains, like BSC and opBNB, directly.

    interface IObjectHub {\n    /** \n     * @dev  Query the contract address of object NFT.\n     * @return The contract address of object token.\n     * Each object will be mapped as a NFT on BSC.\n     * Object ID and NFT token ID are the same.\n     */\n    function ERC721Token() external view returns (address);\n\n    /**\n     * @dev delete a object and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The object's id.\n     */\n    function deleteObject(uint256 id) external payable returns (bool);\n\n    /**\n     * @dev delete a object and send cross-chain request from BSC to GNFD.\n     * Callback function will be called when the request is processed.\n     *\n     * @param id The object's id.\n     * @param callbackGasLimit The gas limit for callback function.\n     * @param extraData Extra data for callback function.\n     */\n    function deleteObject(uint256 id, uint256 callbackGasLimit, CmnStorage.ExtraData memory extraData) external payable returns (bool);\n\n    /**\n     * @dev Prepare the delete object cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The object's id.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteObject(\n        address sender,\n        uint256 id\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete object cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The object's id.\n     * @param callbackGasLimit The gas limit for callback function\n     * @param extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeleteObject(\n        address sender,\n        uint256 id,\n        uint256 callbackGasLimit,\n        ExtraData memory extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n}\n

    IPermissionHub

    The PermissionHub contract provides the following interfaces to manage permission on EVM-compatible chains, like BSC and opBNB, directly.

    interface IPermissionHub {\n    /** \n     * @dev  Query the contract address of permission NFT.\n     * @return The contract address of permission token.\n     * Each permission policy will be mapped as a NFT on BSC.\n     * Policy ID and NFT token ID are the same.\n     */\n    function ERC721Token() external view returns (address);\n\n    /**\n     * @dev delete a policy and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The policy's id.\n     */\n    function deletePolicy(uint256 id) external payable returns (bool);\n\n    /**\n     * @dev delete a policy and send cross-chain request from BSC to GNFD.\n     *\n     * @param id The policy's id.\n     * @param _extraData Extra data for callback function.\n     */\n    function deletePolicy(uint256 id, PermissionStorage.ExtraData memory _extraData) external payable returns (bool);\n\n    /**\n     * @dev create a policy and send cross-chain request from BSC to GNFD.\n     *\n     * @param data policy data encoded by protobuf.\n     * @param _extraData Extra data for callback function.\n     */\n    function createPolicy(\n        bytes calldata _data, \n        PermissionStorage.ExtraData memory _extraData\n    ) external payable returns (bool);\n\n    /**\n     * @dev create a policy and send cross-chain request from BSC to GNFD.\n     *\n     * @param _data policy data encoded by protobuf.\n     */\n    function createPolicy(bytes calldata _data) external payable returns (bool);\n\n    /**\n     * @dev Prepare the create policy cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param _data policy data encoded by protobuf.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreatePolicy(\n        address sender, \n        bytes calldata _data\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the create policy cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param _data policy data encoded by protobuf.\n     * @param _extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareCreatePolicy(\n        address sender, \n        bytes calldata _data, \n        PermissionStorage.ExtraData memory _extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete policy cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The policy's id.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeletePolicy(\n        address sender, \n        uint256 id\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n\n    /**\n     * @dev Prepare the delete policy cross-chain msg data.\n     * This function is used to assist with `MultiMessage`.\n     *\n     * @param sender The supposed msg sender of the cross-chain request.\n     * @param id The policy's id.\n     * @param _extraData Extra data for callback function.\n     *\n     * @return (ChannelID, MsgBytes, RelayerFee, AckRelayerFee, SenderAddress).\n     */\n    function prepareDeletePolicy(\n        address sender, \n        uint256 id, \n        PermissionStorage.ExtraData memory _extraData\n    ) external payable returns (uint8, bytes memory, uint256, uint256, address);\n

    IMultiMessage

    MultiMessage provides aggregation capabilities to support the atomicity of composite operations.

    interface IMultiMessage {\n    function sendMessages(\n        address[] calldata _targets,\n        bytes[] calldata _data,\n        uint256[] calldata _values\n    ) external payable returns (bool);\n}\n

    IGreenfieldExecutor

    Most native operations can be achieved by GreenfieldExecutor, like create payment account, deposit to payment account, withdraw from payment account, migrate bucket, cancel migrate bucket, update bucket info, toggle SP as delegated agent, set bucket flow ratelimit, copy object, update object info, set tag.

    interface IGreenfieldExecutor {\n    function execute(uint8[] calldata _msgTypes, bytes[] calldata _msgBytes) external payable returns (bool);\n}\n
    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/","title":"Resource Mirroring - BNB Greenfield Cross Chain","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/#resource-mirroring","title":"Resource Mirroring","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/#overview","title":"Overview","text":"

    Greenfield Blockchain offers resources like buckets, objects, and groups for mirroring on EVM-compatible chains (e.g., BSC, opBNB) as ERC-721 NFTs.

    Buckets serve as containers for objects, which are data files with metadata, while groups are sets of accounts with shared permissions. Additionally, group members\u2019 permissions can be mirrored as ERC-1155 tokens. Currently, these NFTs are non-transferable, with plans to introduce transferability soon.

    Mirrored resources on EVM chains can be managed via smart contracts, impacting data\u2019s storage format and access permissions. Changes on EVM chains reflect on Greenfield, enhancing data access and manipulation flexibility. This integration fosters a more efficient data management process.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/#how-to-mirror","title":"How to Mirror","text":"

    Mirroring objects from BNB Greenfield to BSC is not done automatically with the creation of the resource. Users have to manually trigger the mirroring process for selected objects, either at the bucket or object level or group, as it requires transaction gas. This allows users to have control over which objects are mirrored while being aware of the associated costs.

    The changes made to mirrored objects on BSC are propagated to BNB Greenfield once the corresponding transactions are finalized on both blockchains. BSC has a block finality of 3 seconds, while BNB Greenfield has a block finality of 2 seconds. As a result, the changes should be reflected within a maximum block finality of 3 seconds, which is the longer of the two block finality times.

    Once an object is mirrored from BNB Greenfield to BSC, it can only be managed on BSC and cannot be reverted or \u201cun-mirrored\u201d back to Greenfield for management through Greenfield. However, it is worth noting that the ability to \u201cun-mirror\u201d objects back to Greenfield may be introduced in future releases, providing the option to manage mirrored objects through Greenfield after being mirrored to BSC.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/#what-can-be-achieved-through-mirroring","title":"What can be achieved through mirroring","text":"

    Currently changing any metadata attributes of the object, which includes information about its properties, permissions, and other relevant attributes. For instance, to alter an object\u2019s permissions on BNB Greenfield, a user can execute an on-chain transaction on BSC. This transaction, specifying the permission changes, sends a message via relayers from BSC to Greenfield. Upon receiving the message, Greenfield updates the object\u2019s metadata as requested.

    During the mirroring process from BNB Greenfield to BSC, the content of the file itself is not copied. This means that neither the data nor the file metadata, which is stored on the BNB Greenfield blockchain, is transferred to BSC. Consequently, there is no size limit imposed on the mirroring process since the actual file content is not duplicated. The ownership of the resource is changed too during the mirroring process.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/","title":"Resources Mirroring with CLI - BNB Greenfield Cross Chain Integration","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#resources-mirroring-with-cli","title":"Resources Mirroring with CLI","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#introduction","title":"Introduction","text":"

    During the mirroring process from BNB Greenfield to BSC, the content of the file itself is not copied. This means that neither the data nor the file metadata, which is stored on the BNB Greenfield blockchain, is transferred to BSC. Consequently, there is no size limit imposed on the mirroring process since the actual file content is not duplicated.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#mirror-objects","title":"Mirror Objects","text":"

    Objects can be mirrored on the BSC as ERC-721 NFTs

    Example command to mirror to BSC testnet:

    gnfd-cmd object mirror --bucketName yourBucketName --objectName yourObjectName --destChainId 97\n

    Example output:

    mirror object succ, txHash: 0774F400EBD42FAB009A6B3C303EF8625B57AB551E0F065C546B892167938122\n
    You can go to GreenfieldScan to view the details of mirror operation.

    Then, go to BscScan and you can find out that there is a NFT transferred to you.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#mirror-buckets","title":"Mirror Buckets","text":"

    Mirror buckets are the same procedure and mirror objects.

    Example command to mirror to BSC testnet:

    gnfd-cmd object mirror --bucketName yourBucketName  --destChainId 97\n

    Example output:

    mirror bucket succ, txHash: 0xba1ca47a2271864b2010158b13535331301ba3289aab8e373503e91e3a41d0a7\n
    You can go to GreenfieldScan to view the details of mirror operation.

    Then, go to BscScan and you can find out that there is a NFT transferred to you.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirror/#mirror-group","title":"Mirror Group","text":"

    The members within a group, which represent permissions to specify resources, can be mirrored as ERC-1155 token.

    Example command to mirror to BSC testnet:

    // mirror a group as NFT to BSC, you might use group id or groupName to identidy the group\ngnfd-cmd group mirror --id 1\n// irror a group with group id\ngnfd-cmd group mirror --groupName yourGroupName\n

    Example output:

    mirror_group:\ntransaction hash: 99A749ECC3CEB8B7CF4B8132A19D1A04EF7247F8549477B6AD28CA69BD11E66A\n
    You can go to GreenfieldScan to view the details of mirror operation.

    Then, go to BscScan and you can find out that there is a NFT transferred to you.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/","title":"Cross Chain Program FAQ - BNB Greenfield Cross Chain Integration","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#cross-chain-program-faq","title":"Cross Chain Program FAQ","text":""},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#what-are-the-advantages-of-mirroring","title":"What are the advantages of mirroring?","text":"

    By transferring control over objects to the smart contract on BSC and allowing on-chain management, object mirroring enables greater flexibility and control over decentralized storage on BNB Greenfield to all dApps on BSC. It leverages the capabilities of the BSC and its smart contract functionality to provide enhanced functionality and interoperability between the two platforms.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#how-mirroring-is-actually-implemented-on-bsc","title":"How mirroring is actually implemented on BSC?","text":"

    Mirroring on BSC allows for the replication of resources from the Greenfield Blockchain to BSC as non-fungible tokens (NFTs). These resources include buckets, objects, and groups, which are represented as NFTs conforming to the ERC-721 standard. Additionally, the members within a group can be mirrored as ERC-1155 tokens, representing permissions.

    Once mirrored on BSC, these resources can be managed directly by smart contracts on the BSC network. Any operations performed on BSC will impact the storage format, access permissions, and other aspects of the data on Greenfield, ensuring that changes made on BSC are reflected on Greenfield. Currently, the mirrored NFTs are not transferable, but the ability to transfer them will be introduced in the future.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#are-objects-mirrored-by-default-over-to-bsc","title":"Are objects mirrored by default over to BSC?","text":"

    Mirroring objects from BNB Greenfield to BSC is not done automatically with the creation of the object. Users have to manually trigger the mirroring process for selected objects, either at the bucket or object level, as it requires transaction gas. This allows users to have control over which objects are mirrored while being aware of the associated costs.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#how-long-the-changes-are-propagated-from-mirrored-bsc-objects-to-actual-change-on-bnb-greenfield","title":"How long the changes are propagated from mirrored BSC objects to actual change on BNB Greenfield?","text":"

    The changes made to mirrored objects on BSC are propagated to BNB Greenfield once the corresponding transactions are finalized on both blockchains. BSC has a block finality of 3 seconds, while BNB Greenfield has a block finality of 2 seconds. As a result, the changes should be reflected within a maximum block finality of 3 seconds, which is the longer of the two block finality times.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#if-the-object-is-renamed-does-the-mirroring-break-and-need-to-be-remirrored","title":"If the object is renamed, does the mirroring break and need to be \u201cremirrored\u201d?","text":"

    Mirroring in BNB Greenfield is based on the unique object ID and is not influenced by changes to object metadata, including its name. Even if an object is renamed, the mirroring process remains intact, as it is unaffected by such metadata modifications.

    "},{"location":"bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/#can-the-mirrored-object-be-migrated-between-storage-providers","title":"Can the mirrored object be migrated between storage providers?","text":"

    The mirroring process in BNB Greenfield allows for object migration between storage providers because the object\u2019s data and metadata always reside on BNB Greenfield. As the data is not copied over to BSC, the mirroring remains unaffected. This means that migrating the actual content from one storage provider to another does not impact the mirroring process.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/","title":"Blob Hub","text":""},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#blob-hub-bnb-greenfield-as-data-archive-layer-for-evm-l1-chains","title":"Blob Hub: BNB Greenfield as Data Archive Layer for EVM L1 Chains","text":"

    The Greenfield community has recently launched \u201cBlobHub,\u201d a data archive layer designed for all layer 2 blockchains and Dapps which leverages EIP4844 blobs as data availability layer. All historical blobs can be persisted into Greenfield, and users can easily access these blobs whenever they want to query them. BlobHub not only serves Ethereum but also other blockchains that enable EIP4844.

    While each blob can be saved as an object in Greenfield, doing so individually would not be cost-effective. Thanks to the bundle service, which aggregates small files into one bundle for storage in Greenfield, this service can gather blobs from a wide range of blocks, validate their correctness, and upload them to Greenfield efficiently.

    Note: Greenfield will charge a fee for both storing and reading objects from the bucket owner. If there is not enough balance in the bucket payment account, users will be unable to query data until the quota is refilled.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#how-does-blob-hub-work","title":"How Does Blob Hub Work","text":"

    The Blob Hub primarily consists of two components: the blob-syncer and the api-server. To sync blobs to Greenfield, the blob-syncer service continuously fetches blobs from Ethereum and other blockchains and persists them in Greenfield. The api-server handles historical blob query requests from users. The bundle-service can aggregate blobs together, validate their correctness, and upload them to Greenfield efficiently.

    The syncing process ensures that no blob is missing and each blob synced to Greenfield is consistent. This is achieved by running a post-verification process that scans all uploaded blobs again, conducts integrity checks against data already stored in Greenfield, and detects any missing data. Duplicate uploads are prevented by key naming constraints in the Bundle service and Greenfield.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#who-needs-to-access-the-blob-hub","title":"Who Needs to Access the Blob Hub?","text":""},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#layer-2-node","title":"Layer 2 Node","text":"

    Layer 2 nodes that need to sync from the genesis block require access to historical block data via the Blob Hub. By leveraging Greenfield\u2019s robust infrastructure, they can rest assured that the integrity and availability of the stored data remain intact.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#analytical-platform","title":"Analytical Platform","text":"

    For on-chain data analytical builders, the blob hub service offers an alternative to centralized RPC service providers. By relying on a decentralized source, these builders gain access to a wealth of historical blob data without being tethered to centralized entities.

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#query-blobs-from-blob-hub","title":"Query Blobs from Blob Hub","text":"

    Blob hub released its support to Ethereum and BSC now, it is going to support as many EVM chains as possible. The API is 100% compatible with the Beacon Chain and BSC API spec. Developers can get the supported network and endpoints in the doc.

    For more details about the API spec, please refer to BlobHub API

    "},{"location":"bnb-greenfield/for-developers/data-archive/blob-hub/#try-it-out","title":"Try It Out","text":"

    By adopting this innovative solution, stakeholders can ensure the integrity, accessibility, and longevity of blockchain data, thereby supporting a more resilient and transparent digital ecosystem. Don\u2019t miss the opportunity to revolutionize your data handling processes\u2014join the Greenfield community today and set a new standard for blockchain data reliability and security.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/","title":"BlockHub","text":""},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#blockhub","title":"BlockHub","text":"

    BlockHub offers a lightweight, trustless, and decentralized method for accessing blockchain data. It provides a user experience that is fully consistent with the original network\u2019s RPC and P2P access, eliminating the need for users to run full nodes or rely on centralized data providers to fetch block data. Don\u2019t want to trust a third party provider to provide the block data? Greenfield Blockhub is the answer. BlockHub is alive for BSC now.

    Much like Blob Hub, which uses the Bundle Service to archive blobs into a single bundle, BlockHub leverages the bundle service to combine a range of blocks into a single bundle. This approach optimizes storage usage, ensures cost-effectiveness, and maintains data integrity and accessibility.

    Note: Greenfield charges a fee for both storing and accessing objects. If the bucket owner\u2019s payment account lacks sufficient balance, users will be unable to query data until the quota is refilled.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#how-blockhub-operates","title":"How BlockHub Operates","text":"

    The BlockHub comprises three main components:

    The indexing process ensures data integrity by running a post-verification process. This process scans all uploaded blocks, conducts validation checks against data already stored in Greenfield, and detects any missing data.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#who-needs-to-access-the-blockhub","title":"Who Needs to Access the BlockHub?","text":""},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#node-operators","title":"Node Operators","text":"

    Node operators requiring full sync from the genesis block need access to historical block data via the BlockHub. Leveraging Greenfield\u2019s robust infrastructure, they can trust the integrity and availability of the stored data.

    The Greenfield community has launched the Greenfield Peer, a data-seed solution for those who need to run BSC nodes in fullsync mode. For more details, check out this page.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#data-analysts-and-researchers","title":"Data Analysts and Researchers","text":"

    BlockHub offers a valuable resource for data analysts and researchers who need comprehensive access to historical block data. By leveraging BlockHub, they can collect reliable data for analysis, research, and development purposes.

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#accessing-block-data-with-blockhub","title":"Accessing Block Data with BlockHub","text":"

    BlockHub supports BSC now and its API is fully compatible with Ethereum API specifications, ensuring ease of integration for developers. Detailed information about supported networks and endpoints can be found in network and endpoints. For more details about the API spec, please refer to BlockHub API

    "},{"location":"bnb-greenfield/for-developers/data-archive/block-hub/#try-it-out","title":"Try It Out","text":"

    Adopting this innovative solution ensures the integrity, accessibility, and longevity of blockchain data, supporting a more resilient and transparent digital ecosystem. Join the Greenfield community today and set a new standard for blockchain data reliability and security.

    "},{"location":"bnb-greenfield/for-developers/data-archive/data-archive-layer/","title":"Data Archive Layer","text":""},{"location":"bnb-greenfield/for-developers/data-archive/data-archive-layer/#what-is-data-archive-layer","title":"What Is Data Archive Layer?","text":"

    Modular blockchains divide the core functions of a classic blockchain into distinct specialized layers. Data availability layer is the essential component that ensures that transaction data included in each produced block is accessible to every node in the network.

    This layer essentially maintains the integrity and trust of the blockchain, allowing everyone to independently verify the validity of transactions. The data availability layer guarantees access to newly created data, but it does not provide access to the entire historical data. For example, EIP4844 and Celestica will discard blob data older than 18 days.

    The data archive layer is an extension of the data availability layer, ensuring that all historical block data remains publicly accessible after being archived.

    "},{"location":"bnb-greenfield/for-developers/data-archive/light-peer/","title":"Light Peer, a BSC data-seed By Greenfield","text":""},{"location":"bnb-greenfield/for-developers/data-archive/light-peer/#light-peer","title":"Light Peer","text":"

    With the launch of the block-hub, BSC historical block data is now accessible on Greenfield. For those operating BSC nodes in fullsync mode, connecting to the Light peer is a beneficial choice. The Light peer fetches block data from Greenfield and supplies it to BSC nodes via the P2P network.

    "},{"location":"bnb-greenfield/for-developers/data-archive/light-peer/#how-the-light-peer-works","title":"How The Light Peer Works","text":"

    The diagram below illustrates the functionality of the Light peer. While the Light peer does not participate in other operations within the BSC network, it solely provides block data to BSC nodes. It does not persist any data on its own; instead, when it receives requests (GetBodies and GetHeaders) from other BSC nodes, it fetches a bundle of blocks (# of blocks determined by the Block Indexer) from Greenfield and caches them in memory. This ensures the Light peer delivers block data to BSC nodes efficiently.

    "},{"location":"bnb-greenfield/for-developers/data-archive/light-peer/#how-to-interact-with-light-peer","title":"How to interact with Light Peer","text":"

    Utilizing the Light Peer is straightforward. Configure your BSC node to connect to the Light peer by adjusting the settings in your configuration file.

    Navigate to the P2P section of your BSC node configuration file and specify the enode info of the Light peer.

    # other configurations are omitted\n...\n[Node.P2P]\nMaxPeers = 1\nNoDiscovery = true\nTrustedNodes = []\nStaticNodes=[\"enode://a2c586f41d2cc6dc7445e32922305e92b4de7daad718744d12bf105a79715606330535cffae6a0d60c61567ff772796d906fcb72b9cbb578f10de3221bb34015@13.115.90.65:30303?discport=0\"]\n...\n
    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/","title":"RPC Endpoints - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#mainnet","title":"Mainnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#greenfield-chain-id-greenfield_1017-1","title":"Greenfield (chain-id: greenfield_1017-1)","text":"

    The above SPs are joined in the genesis state. For more SP endpoints, you can refer to GreenfieldScan SPs.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#bsc-chain-id-56","title":"BSC (chain-id: 56)","text":"

    You could find more endpoints from here.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#opbnb-chain-id-204","title":"opBNB (chain-id: 204)","text":"

    For more details, you can refer to here.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#blob-hub","title":"Blob hub","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#block-hub","title":"Block Hub","text":"

    Refer to the Block-Hub documentation for more details.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#testnet","title":"Testnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#greenfield-testnet-chain-id-greenfield_5600-1","title":"Greenfield Testnet (chain-id: greenfield_5600-1)","text":"

    The above SPs are joined in the genesis state. For more SP endpoints, you can refer to GreenfieldScan Testnet SPs.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#bsc-testnet-chain-id-97","title":"BSC Testnet (chain-id: 97)","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#opbnb-chain-id-5611","title":"opBNB (chain-id: 5611)","text":"

    For more details, you can refer to here.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/endpoints/#block-hub_1","title":"Block Hub","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/","title":"Network Info","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#network-information","title":"Network Information","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#rpc-endpoints","title":"RPC Endpoints","text":"

    The RPC Endpoints you may need to know to connect to Greenfield.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#bridge","title":"Bridge","text":"

    Greenfield and BSC account systems are fully compatible, using the same address format. This allows users to easily transfer their BNBs between Greenfield and BSC. The following cross-chain bridges are available.

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#mainnet","title":"Mainnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#testnet","title":"Testnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#block-explorers","title":"Block Explorers","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#mainnet_1","title":"Mainnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#testnet_1","title":"Testnet","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#dcellar","title":"DCellar","text":"

    DCellar, as the inaugural application built on the BNB Greenfield, serves as an ultimate client of the BNB Greenfield network. Besides Basic file management and asset management functions, DCellar can also greatly assist developers in comprehending the functionalities of Greenfield:

    Here are the domain names for DCellar: - Mainnet: https://dcellar.io - Testnet: https://testnet.dcellar.io/

    "},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#related-projects","title":"Related Projects","text":""},{"location":"bnb-greenfield/for-developers/network-endpoint/network-info/#other","title":"Other","text":""},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/","title":"Basic File Management with CLI - BNB Greenfield Tutorials","text":""},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#introduction-to-file-management-with-cli","title":"Introduction to file management with CLI","text":""},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#introduction","title":"Introduction","text":"

    Backing up files is an essential practice for any development process. The benefits initially might not seem straightforward, but backups provide a safety net for disaster recovery, ensuring that data can be restored in the event of hardware failures, accidental deletions, or natural disasters.

    Backups often encompass local changes and experiments outside of the repository, ensuring that valuable work is not lost and can be integrated into the main codebase. Furthermore, repositories may not effectively handle non-code files and operational documentation, making backups crucial for their preservation. By providing redundancy and data integrity, backups reduce the risk of relying solely on a single repository. They also facilitate long-term archiving, ensuring access to historical data even if repository policies change or there is a switch to a different provider.

    Traditional cloud storage services, while convenient, are centralized and often have clauses in their terms and conditions that allow them to share your data with third parties and government agencies. This is where BNB Greenfield, a new decentralized storage on BNB Chain, comes in as a more secure and private alternative for backing up your files.

    In this tutorial, we will guide you through the process of setting up your environment, installing the necessary tools, and effectively backing up your files to BNB Greenfield, leveraging the benefits of decentralized storage while ensuring data security and ownership.

    We will also cover how to interact with the CLI tool, choose storage providers, manage your account balance, and manage buckets and uploaded files.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#setting-up-the-environment","title":"Setting Up the Environment","text":""},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#installation","title":"Installation","text":"

    Greenfield Command is a powerful command line to interact with Greenfield. To begin, you will need to install the BNB Greenfield command line tool follow the instruction from CLI github page.

    When running commands that interact with the greenfield, if there is no config/config.toml file under the path and the commands runs without \u201c\u2013config\u201d flag, the tool will generate the config/config.toml file automatically which is consistent with the network configuration under the path.

    Config file example will set up the necessary RPC address and chain id:

    MainnetTestnet
    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\nchainId = \"greenfield_1017-1\"\n
    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\nchainId = \"greenfield_5600-1\"\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#impport-account-and-generating-keystore","title":"Impport Account and Generating Keystore","text":"

    To set up your identity on the local machine and generate a keystore file, you will need to create the private file which will hold the identity private key. You can export your private key from MetaMask and write it into a local file as plaintext (You can select \u201cAccount Details\u201d from the dropdown menu of MetaMask. Click on the \u201cExport Private Key\u201d button at the bottom of the page. Once you have the files ready, run the following command \u201caccount import [keyfile]\u201d :

    // import key and generate a keystore file\n// key.txt indicates the private key file\ngnfd-cmd account import key.txt\n

    The terminal will prompt user to enter the password information. Users can also specify the password file path by using the \u201c\u2013passwordfile\u201d. While the password doesn\u2019t have any restriction on the length or complexity, it\u2019s better to follow generally recommended principles.

    This command will create a keystore file and store it in the path \u201ckeystore/key.json\u201d under the home directory of the system or the directory set by \u201c-home\u201d and will be picked up by the CLI for commands that require identity and payment. After generating the keystore file, make sure to delete the key.txt file with the private key inside.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#interacting-with-bnb-greenfield","title":"Interacting with BNB Greenfield","text":"

    BNB Greenfield is built on a distributed architecture where storage providers play a crucial role. The network consists of multiple storage providers that offer their resources to store and retrieve data from users. When using BNB Greenfield, users have the flexibility to choose which storage providers to utilize based on several factors, including price, terms and conditions, and network performance.

    When selecting storage providers, users can query the decentralized storage network through the CLI tool to obtain information about available providers. The list of providers will include their operator addresses and corresponding endpoints. Users can then analyze the providers based on the aforementioned factors and choose the ones that best align with their requirements.

    For the advanced use cases, users can diversify their storage across multiple providers to enhance redundancy and mitigate the risk of data loss. This approach distributes data among different providers, ensuring that even if one provider experiences issues, the data remains accessible from other providers. By carefully selecting storage providers based on price, terms and conditions, and network performance, users can optimize their decentralized storage experience and maintain control over their data while enjoying the benefits of enhanced security and privacy.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#selecting-storage-providers","title":"Selecting Storage Providers","text":"

    To query the network and get a list of storage providers, execute:

    ./gnfd-cmd sp ls\n

    The result should display a list of storage providers. For mainnet, there are several active storage providers, which can be used for development purposes.

    name     operator address                           endpoint                               status\nbnbchain 0x231099e40E1f98879C4126ef35D82FF006F24fF2 https://greenfield-sp.bnbchain.org:443 IN_SERVICE\ndefibit  0x05b1d420DcAd3aB51EDDE809D90E6e47B8dC9880 https://greenfield-sp.defibit.io:443   IN_SERVICE\nninicoin 0x2901FDdEF924f077Ec6811A4a6a1CB0F13858e8f https://greenfield-sp.ninicoin.io:443  IN_SERVICE\nnariox   0x88051F12AEaEC7d50058Fc20b275b388e15e2580 https://greenfield-sp.nariox.org:443   IN_SERVICE\nlumibot  0x3131865C8B61Bcb045ed756FBe50862fc23aB873 https://greenfield-sp.lumibot.org:443  IN_SERVICE\nvoltbot  0x6651ED78A4058d8A93CA4979b7AD516D1C9010ac https://greenfield-sp.voltbot.io:443   IN_SERVICE\nnodereal 0x03c0799AD70d19e723359E036a83E8f44f4B8Ba7 https://greenfield-sp.nodereal.io:443  IN_SERVICE\n

    The price for each storage provider can be checked using the operator address, for example:

    ./gnfd-cmd sp get-price 0x231099e40E1f98879C4126ef35D82FF006F24fF2\n

    The response will retrieve the price for reading the data, as well as for storing the data per second.

    get bucket read quota price: 0.1469890427  wei/byte\nget bucket storage price: 0.02183945725  wei/byte\nget bucket free quota: 1073741824\n

    To deduce the price for gigabytes (GB) per month from the metric of data usage in wei/byte, one needs to multiply the result by 0.002783138807808, as there are 1,073,741,824 bytes in 1 GB, 2,592,000 seconds in a month (30 days * 24 hours * 60 minutes * 60 seconds), and 10^18 wei in 1 BNB.

    The result will be the price for storing or transferring data in gigabytes per month, expressed in BNB. This calculation takes into account the rate of data usage and the duration of a month. Following the returned rate of wei/byte/sec, the converted amounts are:

    get bucket read quota price: 0.00041 BNB/GB/month\nget bucket storage price: 0.00006 BNB/GB/month\n

    Keep in mind that the pricing model and calculations may vary depending on the specific storage provider you are using. Always refer to the documentation or provider\u2019s information for accurate and up-to-date pricing details.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#account-management","title":"Account Management","text":"

    While BNB Smart Chain (BSC) and BNB Greenfield define their accounts in the same format, it\u2019s important to understand that they are two separate blockchains with distinct ledgers. As a result, users need to manage their balances separately on both BSC and BNB Greenfield blockchains.

    To transfer test BNB from the BSC to BNB Greenfield, users can utilize the dCellar application. By using the dCellar application, users can initiate the transfer process from their BSC address to their BNB Greenfield address.

    For testnet, users can acquire test BNB tokens for testing purposes by using a test faucet provided by BNB Greenfield which can be accessed at https://gnfd-bsc-faucet.bnbchain.org/. By visiting the faucet website, users can request a certain amount of test BNB tokens to be sent to their BSC testnet address.

    The balance can be checked using the following command:

    ./gnfd-cmd bank balance --address 0x14cfe3777565d942f7a3e1d1dcffd7945170c8fe\n

    And the result will be the current balance:

    balance: 10001464255952380934 weiBNB\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#object-operations","title":"Object Operations","text":"

    In BNB Greenfield objects and buckets are key components. Buckets are containers used to organize and manage data, while objects are the actual files stored within those buckets. Buckets serve as top-level storage units with unique names, and objects have unique identifiers within their respective buckets. Users can perform operations on objects, such as uploading, downloading, and deleting, while applying permissions and access controls at the bucket and object level. This structure allows for efficient storage, organization, and retrieval of data in a decentralized storage network.

    To create a bucket one need to call the following storage make-bucket command with the desired bucket name.

    ./gnfd-cmd bucket create gnfd://bucket123123123\n

    The operation will automatically choose a storage provider and submit a transaction to BNB Greenfield blockchain to write the associated metadata. Alternatively you can provide storage provider address, that is operator-address, if a specific provider should be used. The result should look something similar to the following:

    choose primary sp: https://greenfield-sp.bnbchain.org:443\ncreate bucket bucket123123123 succ, txn hash: 0x6c89316c5912cda8b69eac6e96aa644d374c39c635e07fae4297e03496e7726a\n

    As you can see, the result returns a transaction hash, which one can inspect using the block scanner, e.g. https://greenfieldscan.com. Going to https://greenfieldscan.com/tx/0x6c89316c5912cda8b69eac6e96aa644d374c39c635e07fae4297e03496e7726a, will show all the details of the transaction.

    Notice that we in the details we can see the bucket owner details, moi; primary storage provider address, and the payment address. Since we haven\u2019t created a separate payment account, our default account will serve as the payment account as well.

    With regards to the storage provider address, if you remember, it was picked for us automatically as https://greenfield-sp.bnbchain.org:443. And from Selecting Storage Providers section we can see that its address is indeed 0x231099e40E1f98879C4126ef35D82FF006F24fF2.

    Lastly, it\u2019s time to upload a file, but before we upload anything, let\u2019s create one with a sample text using the echo command as follows:

    echo 'Random sample text' > test4.txt\n

    Finally to upload the file to our newly created bucket bucket123123123, one needs to execute the following command:

    ./gnfd-cmd object put  --contentType \"text/xml\" --visibility private ./test4.txt  gnfd://bucket123123123/test4.txt\n
    Notice that we\u2019ve provided the visibility flag and made the file private. The successful result should be similar to the following:
    create object test4.txt on chain finish, txn Hash: 0x5a885b7da8e8eb6921c84540d29b385b2dcee1f5ebdb4bb6c9219cf82e6ca80d\nput object test4.txt successfully \n

    Similarly, going to https://greenfieldscan.com/tx/0x5a885b7da8e8eb6921c84540d29b385b2dcee1f5ebdb4bb6c9219cf82e6ca80d will show the details of the file upload. Here, observe the transaction payload and scroll to the \u201cvisibility\u201d attribute, which confirms the privacy status.

    {\"key\":\"visibility\" \"value\":\"\\\"VISIBILITY_TYPE_PRIVATE\\\"\" }\n

    After successfully uploading the file, let\u2019s verify the content of the file and compare it to the one we\u2019ve uploaded - they should be identical.

    ./gnfd-cmd object get gnfd://bucket123123123/test4.txt ./test4-copy.txt\n

    The operation will download the file and output the length of the file, as follows:

    download object test4.txt successfully, the file path is ./test4-copy.txt, content length:19\n

    If you know the sp endpoint that object belongs to, you can optimize the download speed by add \u2013spEndpoint flag to download cmd, such as:

    ./gnfd-cmd object get --spEndpoint https://gnfd-testnet-sp3.nodereal.io gnfd://bucket123123123/test4.txt ./test4-copy.txt\n

    To validate the integrity of the file, we can compare its content to the originally uploaded one. Empty output confirms there are no differences.

    diff test4.txt test4-copy.txt \n
    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#upload-multiple-objects","title":"Upload multiple objects","text":"

    gnfd-cmd also support uploads all files from a folder recursively.

    Let\u2019s say that there is a folder called website where you store all the files for your website.

    $ ls\nindex.html  plato.jpeg  styles.css\n
    To upload all these files into your bucket, you can run the following commands:
    gnfd-cmd object put --recursive ./website gnfd://ylatitsb\n

    Please note that --recursive is used to put all files or objects under the specified directory or prefix in a recursive way. The default value is false

    The successful result should be similar to the following:

    ================================================\nYour batch upload is submitted as a task, task ID is sdgerdf-sfdgasg-1237hedfg\nYou can check your task status and progress by using cmd as below:\n\n- List all your tasks: ./gnfd-cmd task ls\n- Check status: ./gnfd-cmd task status --task.id taskID\n- Retry (in case this process is killed accidentally): ./gnfd-cmd task retry --task.id taskID\n- Delete task: ...\n\n>>================================================\nUpload Task building\n\nsealed index.html\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#task-operations","title":"Task Operations","text":"

    When object put \u2013recursive is used, tasks are automatically created

    You can view/retry/delete tasks with gnfd-cmd task

    Using the gnfd-cmd task requires a new session to be opened while the gfnd-cmd object put --recursive is in progress. If the current session is interrupted, the put object is interrupted

    ./build/gnfd-cmd task  status --taskId abe92a9a-1aa0-45be-9e0b-4cd400c38a06\n
    Viewing Task status taskId will be generated after the gfnd-cmd object put --recursive
    Folder: ./website\nStatus: created\nsealed            index.html\nwait_for_upload   styles.css\n
    ./build/gnfd-cmd task  retry --taskId abe92a9a-1aa0-45be-9e0b-4cd400c38a06\n

    gfnd-cmd object put --recursive will be used to retry after a failure or interruption

    task: abe92a9a-1aa0-45be-9e0b-4cd400c38a06\nfolder name: ./website\nretrying...\n\nsealed index.html\n

    ./build/gnfd-cmd task  delete --taskId abe92a9a-1aa0-45be-9e0b-4cd400c38a06\n
    You can delete a task by deleting it

    You can go to GreenfieldScan to view the change of your bucket.

    "},{"location":"bnb-greenfield/for-developers/tutorials/file-management-overview/#conclusion","title":"Conclusion","text":"

    Overall, backups during software development offer peace of mind, efficient recovery, and safeguarding of the project\u2019s integrity. They minimize downtime and prevent significant setbacks.

    After gaining familiarity with the command line tool and BNB Greenfield through this tutorial, the next step is to explore and experiment with creating files, buckets, and permission groups. By creating multiple files and organizing them into buckets, users can gain hands-on experience with the storage capabilities of BNB Greenfield.

    It is highly recommended for users to engage in hands-on exploration by trying out different wallets and understanding the basic operations and permissioning mechanisms. This will provide a deeper understanding of how BNB Greenfield functions and how to effectively manage and secure data within the decentralized storage system.

    This practical experience will pave the way for comprehending more advanced topics discussed in future articles, such as programmability and BNB Greenfield\u2019s innovative concept of flow-based billing and asset monetization. By exploring the diverse functionalities and experimenting with different configurations, users can unlock the full potential of BNB Greenfield and unlock its new data economy concepts.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/","title":"Hosting a Website on Greenfield - BNB Greenfield Tutorials","text":""},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#creating-and-uploading-a-website-with-cli","title":"Creating and uploading a website with CLI","text":""},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#introduction","title":"Introduction","text":"

    In today\u2019s era, having a website has become essential for individuals and businesses alike. With advancements in AI, tools like ChatGPT and Bard can help create a simple website or boilerplate with just a few sentences. This tutorial will guide you through the process of creating and uploading a website to BNB Greenfield, a decentralized storage on the BNB Chain.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#creating-a-website","title":"Creating a website","text":"

    A website typically consists of HTML pages, CSS stylesheets, and JavaScript scripts for enhanced interactivity. These files work together to create the visual layout, design, and functionality of the website. Go to the AI tool of your choice and type something like \u201cCreate a website about Plato\u2019s biography with images\u201d. And ideally, after a few iterations, you\u2019ll get to a decent-looking website.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#deploying-a-website","title":"Deploying a website","text":"

    Deploying a website to a web hosting platform is crucial because it makes the website publicly accessible and ensures its availability to users. When a website is hosted on a cloud server it becomes accessible to anyone with an internet connection. Users can access the website by typing its URL or domain name into a web browser.

    In the case of BNB Greenfield, the decentralized network of storage providers contributes to increased availability by distributing the website\u2019s files across multiple nodes. Additionally, decentralized networks like BNB Greenfield provide data redundancy by storing multiple copies of the website\u2019s files on different nodes, reducing the risk of data loss. BNB Greenfield prioritizes security measures to protect websites and their data from unauthorized access, cyber threats, and data breaches.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#creating-a-bucket","title":"Creating a Bucket","text":"

    To start, create a separate bucket for your website on BNB Greenfield using the following command:

    ./gnfd-cmd bucket create --visibility=public-read gnfd://my-plato-website --primarySP 0x231099e40E1f98879C4126ef35D82FF006F24fF2\n

    The example return message is like the following:

    make_bucket: my-plato-website\ntransaction hash:  E083FB2647D0A53640B63AD1DB8EFA0E1C5CC05454C0774E3DB2A4822E73D423\n

    You can verify the transaction in explorer here.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#uploading-supporting-files","title":"Uploading Supporting Files","text":"

    Next, upload the stylesheet and image files to your newly created bucket. Set the visibility flag as public-read to make the files accessible to everyone:

    ./gnfd-cmd object put --visibility=public-read ./plato.jpg gnfd://my-plato-website/plato.jpg ./gnfd-cmd object put --visibility=public-read ./styles.css gnfd://my-plato-website/styles.css\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#bnb-greenfield-url","title":"BNB Greenfield Url","text":"

    BNB Greenfield utilizes a specific URL format known as the BNB Greenfield Url to identify and access objects within its decentralized storage. The URL format follows the pattern: gnfd://<bucket_name><object_name>?[parameter]*.

    Let\u2019s break down the components of this format:

    1. \u201cgnfd://\u201d - This is the fixed leading identifier that indicates the URL is associated with BNB Greenfield. It is mandatory and serves as a marker for Greenfield URLs.

    2. bucket_name - Refers to the name of the bucket where the object is stored. It is a mandatory component and helps identify the specific storage location within BNB Greenfield.

    3. object_name - Represents the name of the object (e.g., file) within the bucket. It is also mandatory and allows for precise identification of the desired resource.

    4. parameter - This component is optional and consists of a list of key-value pairs. Parameters provide additional information for the URI, enabling customization or specific functionality. Examples of parameters could include cache settings or other metadata.

    Additionally, BNB Greenfield allows Service Providers (SPs) to register multiple endpoints for accessing their services. For instance, an SP named \u201cSP1\u201d might request users to download objects via a URL like https://greenfield.sp1.com/download. The complete RESTful API for downloading an object from \u201cSP1\u201d would resemble: https://greenfield.sp1.com/download/mybucket/myobject.jpg, where \u201cmybucket\u201d is the bucket name and \u201cmyobject.jpg\u201d is the specific object within that bucket.

    In the context of our website, the bucket was created under the SP2 service provider, and the serving endpoint for accessing the website\u2019s content is https://gnfd-testnet-sp-2.bnbchain.org/. This endpoint allows users to access the website\u2019s files, such as HTML, CSS, images, and more, stored within the designated bucket on BNB Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#updating-the-references","title":"Updating the references","text":"

    Once the supporting files are uploaded, update the links in your HTML file to point to the correct URLs. Following the BNB Greenfield Url pattern, we need to update the URLs in our index.html file to ensure correct file retrieval.

    For example, if we had an image file named plato.jpg located in the \u201cimages\u201d directory, previously the URL reference would be \u201cimages/plato.jpg\u201d. However, with BNB Greenfield\u2019s URL format, we need to modify it to include the serving endpoint and the specific bucket name.

    Instead of \u201cimages/plato.jpg\u201d, we would change it to https://gnfd-testnet-sp-2.bnbchain.org/view/my-plato-website/images/plato.jpg, where \u201cmy-plato-website\u201d corresponds to the bucket name in which the file is stored. This updated URL ensures that the browser can retrieve the correct image file from BNB Greenfield.

    But things get better! Since the BNB Greenfield URL format remains identical for all files within the same bucket, we can simplify the URLs for files residing within the same bucket. In the case of the CSS file, we can reference it using a relative path without specifying the full URL. For example:

    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">\n

    Similarly, for the image file plato.jpg, we can use a relative path without the need to specify the full URL:

    <img src=\"plato.jpg\" alt=\"Plato\" class=\"plato-image\">\n

    By using relative paths, the browser will correctly fetch the CSS file and the image file from the same bucket within BNB Greenfield, eliminating the need to include the full path in these specific cases.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#uploading-html-files","title":"Uploading HTML Files","text":"

    Upload the modified index.html file to your bucket using the following command:

    ./gnfd-cmd object put --visibility=public-read --contentType=text/html ./index.html \ngnfd://my-plato-website/index.html \n

    Example output:

    object index.html created on chain\ntransaction hash:  20921F3C1DBE3F911217CE82BDC9DC2A745AF61912651A5F9D80F10989A8FC20\n\nsealing...\nupload index.html to gnfd://my-plato-website/index.html\n

    Now, let\u2019s eagerly click the link to view our brand new website at https://gnfd-testnet-sp1.bnbchain.org/view/my-plato-website/index.html and feel the anticipation building up.

    \ud83e\udd41Drum beat\u2026

    But, oh no! Something went awry. Instead of the website loading, the file started downloading automatically. Frustration sets in, and I embarked on a lengthy debugging journey, spending a good hour trying to figure out the issue.

    Finally, I discovered the culprit: we forgot to specify the content type for the files, making them unrecognizable and causing them to be downloaded instead of served.

    However, let\u2019s not forget that BNB Greenfield is an immutable storage. So to update the file, we must first delete it and then reupload it.

    To accomplish this, I used the power of the \u2018object delete\u2019 command:

    ./gnfd-cmd object rm gnfd://my-plato-website/index.html\n

    Wait for the confirmation that the file was successfully deleted, accompanied by a transaction hash: 4B12BCF26525C1B661389529524DF14E23164D000FA47FB2E0D0BE26B131E04A.

    And reupload the html file, this time accompanied by the content-type flag:

    ./gnfd-cmd object put --visibility=public-read --contentType=text/html ./index.html gnfd://my-plato-website/index.html\n

    \ud83e\udd41\ud83e\udd41Drum beat intensifies\u2026

    Oh, no! The website still looks horrendous, and worse yet, the image of Plato is nowhere to be found. Frustration turned into disappointment as we discovered that the browser was throwing an error due to an incorrect MIME type. It refused to apply the styles from https://gnfd-testnet-sp-2.bnbchain.org/view/my-plato-website/styles.css because the MIME type was set as \u2018text/plain\u2019, which is not a supported stylesheet MIME type when strict MIME checking is enabled. Fear not! The error looks familiar and we already know exactly what needed to be done. So swiftly deleting the problematic files and reuploading them correctly this time:

    ./gnfd-cmd object rm gnfd://my-plato-website/plato.jpg\n./gnfd-cmd object rm gnfd://my-plato-website/styles.css\n
    And then, with a determined spirit:
    ./gnfd-cmd object put --visibility=public-read --contentType=image/jpeg ./plato.jpg gnfd://my-plato-website/plato.jpg \n./gnfd-cmd object put --visibility=public-read --contentType=text/css ./styles.css gnfd://my-plato-website/styles.css\n

    \ud83e\udd41\ud83e\udd41\ud83e\udd41Drum beat crescendos\u2026

    And finally, we heard the triumphant sound of trumpets!

    However, as we gaze upon the site, we can\u2019t help but admit that it doesn\u2019t look particularly astonishing. It falls short of our grandest expectations. Yet, considering that we generated and uploaded it in just a matter of minutes, it\u2019s still a decent outcome given our investment of time and effort.

    The content and image look good though, it just needs more love with styling\u2026but that\u2019s a story for another tutorial.

    "},{"location":"bnb-greenfield/for-developers/tutorials/hosting-websites-overview/#conclusion","title":"Conclusion","text":"

    Our journey with website development has been filled with ups and downs. We encountered challenges along the way, but with perseverance and a little debugging, we managed to deploy our website successfully.

    BNB Greenfield\u2019s URL format and immutable storage principles require to be mindful of content types and careful when updating files. Despite the minor setbacks, BNB Greenfield remains a valuable platform for deploying websites, offering increased availability, reliability, and quite easy command tools.

    Hope you enjoyed it and looking forward to see your websites on BNB Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/","title":"Overview - BNB Greenfield Tutorials","text":""},{"location":"bnb-greenfield/for-developers/tutorials/overview/#overview-building-decentralized-applications-dapps-with-bnb-greenfield","title":"Overview: Building Decentralized Applications (dApps) with BNB Greenfield","text":"

    In this section, we will introduce the two main methods for developing dApps on BNB Greenfield: using smart contracts deployed to BNB Smart Chain (BSC) and interacting directly with BNB Greenfield through our Software Development Kit (SDK) or Command Line Interface (CLI).

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#data-marketplace-demo","title":"Data Marketplace Demo","text":"

    Data marketplace is a data exchange platform where users can freely create, list, trade, and sell data assets, including digital publications, scientific experimental data, and specific domain data.

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#demo-link","title":"Demo Link","text":""},{"location":"bnb-greenfield/for-developers/tutorials/overview/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/overview/#developing-with-smart-contracts-on-bsc","title":"Developing with smart contracts on BSC","text":"

    One of the primary methods for building dApps with BNB Greenfield is by deploying smart contracts to the BSC. Smart contracts are self-executing programs that facilitate and enforce the execution of agreements without the need for intermediaries.

    In this section, we will guide you through the process of creating, deploying, and interacting with smart contracts on BSC using popular development frameworks like Solidity and Truffle. You can find detailed tutorials and examples for developing dApps using smart contracts in the Building Smart Contract dApps section.

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#interacting-with-bnb-greenfield-through-sdk-and-cli","title":"Interacting with BNB Greenfield through SDK and CLI","text":"

    BNB Greenfield offers two native application options for interacting with the platform without involving the development of smart contracts:

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#software-development-kit-sdk","title":"Software Development Kit (SDK)","text":"

    The Software Development Kit (SDK) is a powerful set of tools, libraries, and APIs that enable seamless integration with BNB Greenfield\u2019s decentralized storage system. The SDK allows you to build dApps using only the SDK functionalities, without the need to develop smart contracts. With the SDK, you can store and retrieve data, manage access controls, and handle encryption to ensure the privacy and security of your dApp\u2019s data.

    "},{"location":"bnb-greenfield/for-developers/tutorials/overview/#command-line-interface-cli","title":"Command Line Interface (CLI)","text":"

    The Command Line Interface (CLI) is another native application provided by BNB Greenfield, allowing you to interact with the platform directly from the terminal. The CLI provides various commands to perform essential tasks efficiently, such as uploading files, managing data permissions, and monitoring storage usage. As with the SDK, using the CLI does not involve the development of smart contracts.

    In the following sections, we will delve deeper into each native application, providing step-by-step guides, code snippets, and best practices to empower you to create powerful and innovative dApps without the need for smart contract development.

    You can find more information and detailed instructions in the Building Native dApps section.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/","title":"How to transition from S3 to Greenfield - BNB Greenfield Develop","text":""},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#how-to-transition-from-s3-to-greenfield","title":"How to transition from S3 to Greenfield","text":""},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#introduction","title":"Introduction","text":"

    Greenfield is a blockchain-based decentralized storage solution designed to enhance the decentralization of data ownership and management, allowing users to manage their own data and assets. This platform promotes the development of decentralized applications (dApps) by offering on-chain data permission management and APIs similar to those of Web2, enhancing data security and management capabilities through the introduction of Storage Providers (SPs), which are responsible for providing authentication and storage services.

    In terms of permission management, SPs offer a range of authentication services. Unlike AWS S3, which control user permissions through AWS Keys and AWS Secrets, SPs in Greenfield use private keys for permission control. This means that on the Greenfield platform, permission authentication is reliant on blockchain technology, ensuring security and decentralization, while also extending blockchain functionalities, including permission authentication and data storage capabilities.

    In Greenfield\u2019s design, users have the freedom to select any SP as their Primary SP, along with additional SPs as Secondary SPs, ensuring both performance and reliability in object storage. Primary SPs are primarily responsible for storing all data segments of an object and directly responding to user read or download requests, whereas Secondary SPs store data blocks generated by Erasure Coding (EC) technology, helping to improve data availability.

    Compared to AWS S3, Greenfield\u2019s distributed storage structure not only enhances data durability and recoverability but also ensures data integrity and verifiability using blockchain technology. Through this approach, Greenfield is committed to promoting a new data economy and dApp model construction, improving the transparency and efficiency of data management, and realizing data decentralization management and ownership proof through blockchain technology.

    We will now showcase on the SDK through Greenfield and AWS S3.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#init-sdk-client","title":"Init SDK client","text":"

    S3

    const (\n    AWSKey          = \"mock-aws-key\"\n    AWSSecret       = \"mock-aws-secret\"\n    Region          = \"us-east-1\"\n)\n\ncfg, err := config.LoadDefaultConfig(context.TODO(),\n    config.WithRegion(Region),\n    config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(AWSKey, AWSSecret, \"\")),\n)\nhandleErr(err, \"LoadDefaultConfig\")\nclient := s3.NewFromConfig(cfg)\n

    For AWS S3, the initialization uses the AWS Key and AWS Secret to create an AWS S3 client to allow user interaction. The Region specifies the region where the user\u2019s bucket is located.

    Greenfield

    const (\n    RpcAddr         = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\" // Greenfield Testnet RPC Address\n    ChainId         = \"greenfield_5600-1\" // Greenfield Testnet Chain ID\n    PrivateKey      = \"mock-private-key\"\n)\nclient, primarySP, err := NewFromConfig(ChainId, RpcAddr, PrivateKey)\nhandleErr(err, \"NewFromConfig\")\n

    For Greenfield, the RPC Address and Chain ID are used to select the specific Greenfield network, with the example above being for the Testnet. Users need to interact using a private key exported from their wallet.

    Greenfield Mainnet Chain ID: greenfield_1017-1

    Greenfield Mainnet RPC

    https://greenfield-chain.bnbchain.org:443

    https://greenfield-chain-ap.bnbchain.org:443

    https://greenfield-chain-eu.bnbchain.org:443

    https://greenfield-chain-us.bnbchain.org:443

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#create-bucket","title":"Create bucket","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\n_, err = client.CreateBucket(context.TODO(), &s3.CreateBucketInput{\n    Bucket: aws.String(BucketName),\n})\nhandleErr(err, \"CreateBucket\")\n

    In AWS S3, the CreateBucket method is called with a configuration object specifying the bucket name. The operation is straightforward, reflecting S3\u2019s cloud storage focus, where the primary concern is the creation and management of storage containers in the cloud.

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\n_, err = client.CreateBucket(context.TODO(), BucketName, primarySP, types.CreateBucketOptions{})\nhandleErr(err, \"CreateBucket\")\n

    For Greenfield, the CreateBucket method also requires a bucket name but includes additional parameters like primarySP, which is obtained during client initialization. The primarySP plays a crucial role in executing and storing corresponding bucket data, indicating a more complex interaction pattern likely due to the blockchain-based nature of Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#list-buckets","title":"List buckets","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\nbucketsList, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})\nhandleErr(err, \"ListBuckets\")\nfor _, bucket := range bucketsList.Buckets {\n    fmt.Printf(\"* %s\\n\", aws.ToString(bucket.Name))\n}\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\nbucketsList, err := client.ListBuckets(context.TODO(), types.ListBucketsOptions{})\nhandleErr(err, \"ListBuckets\")\nfor _, bucket := range bucketsList.Buckets {\n    fmt.Printf(\"* %s\\n\", bucket.BucketInfo.BucketName)\n}\n

    During the initialization of the client for both systems, user information is already obtained, allowing for the return of corresponding buckets through a User object. This process indicates that transitioning from AWS S3 to Greenfield can be achieved with minimal effort and cost.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#delete-bucket","title":"Delete bucket","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\n_, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{\n    Bucket: aws.String(BucketName),\n})\nhandleErr(err, \"Delete Bucket\")\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\n_, err = cli.DeleteBucket(context.TODO(), BucketName, types.DeleteBucketOption{})\nhandleErr(err, \"Delete Bucket\")\n

    The process of deleting a bucket in both AWS S3 and Greenfield is essentially identical, allowing users to easily delete a bucket by simply using its name.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#create-object","title":"Create object","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\n_, err = client.PutObject(context.TODO(), &s3.PutObjectInput{\n    Bucket: aws.String(BucketName),\n    Key:    aws.String(ObjectKey),\n    Body:   file,\n    })\nhandleErr(err, \"PutObject\")\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\ntxnHash, err := cli.CreateObject(context.TODO(), BucketName, ObjectKey, file, types.CreateObjectOptions{})\nhandleErr(err, \"CreateObject\")\n\nerr = cli.PutObject(context.TODO(), BucketName, ObjectKey, int64(fileInfo.Size()),\nfile, types.PutObjectOptions{TxnHash: txnHash})\nhandleErr(err, \"PutObject\")\n

    In the process of creating objects, there is a difference between Greenfield and S3. In Greenfield, it is necessary to first create the object before performing the put object operation. This is because Greenfield requires users to create metadata on the Greenfield blockchain before submitting object to the SP, in order to ensure the integrity of the object.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#list-objects","title":"List objects","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\nobjects, err := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{\n    Bucket: aws.String(BucketName),\n})\nhandleErr(err, \"ListObjectsV2\")\nfor _, item := range objects.Contents {\n    fmt.Printf(\"* %s\\n\", aws.ToString(item.Key))\n}\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n)\n\nobjects, err := cli.ListObjects(context.TODO(), BucketName, types.ListObjectsOptions{\n})\nhandleErr(err, \"ListObjects\")\nfor _, obj := range objects.Objects {\n    log.Printf(\"* %s\\n\", obj.ObjectInfo.ObjectName)\n}\n

    In both AWS S3 and Greenfield, retrieving all objects within a bucket can be easily accomplished by simply using the bucket\u2019s name. This functionality indicates a user-friendly approach to data management, allowing users to efficiently access and manage the contents of their storage without the need for intricate query parameters or complex configuration.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#delete-object","title":"Delete object","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\n_, err = client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{\n    Bucket: aws.String(BucketName),\n    Key:    aws.String(ObjectKey),\n})\nhandleErr(err, \"Delete Object\")\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\n_, err = cli.DeleteObject(context.TODO(), BucketName, ObjectKey, types.DeleteObjectOption{})\nhandleErr(err, \"Delete Object\")\n

    Deleting an object in both AWS S3 and Greenfield is fundamentally similar, enabling users to effortlessly remove an object by specifying both the bucket name and the object name.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#get-object","title":"Get Object","text":"

    S3

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\nresp, err := client.GetObject(context.TODO(), &s3.GetObjectInput{\n    Bucket: aws.String(BucketName),\n    Key:    aws.String(ObjectKey),\n})\nhandleErr(err, \"GetObject\")\n

    Greenfield

    const (\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"test-api.js\"\n)\n\nresp, _, err := cli.GetObject(context.TODO(), BucketName, ObjectKey, types.GetObjectOptions{})\nhandleErr(err, \"GetObject\")\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#summary","title":"Summary","text":"

    AWS S3 and Greenfield offer streamlined data retrieval processes, with users specifying bucket and object names for efficient access. While AWS S3 relies on key-pair authentication and region specification for data locality and access efficiency, Greenfield adopts a blockchain-based approach, using private keys for authentication and RPC Addresses along with Chain IDs for network connectivity. Greenfield enhances service quality through regional RPC endpoints, allowing users to choose the most efficient connection based on their location.

    The structural similarity in SDKs for operations like bucket creation is notable, with Greenfield requiring an additional step to obtain a primarySP during client initialization. This minimal difference suggests a smooth transition for S3 users to Greenfield, highlighting the ease of adaptation due to familiar SDK code structures and metadata handling. Moreover, Greenfield introduces a two-step object management process, offering greater control over object lifecycle states than S3\u2019s more straightforward approach. Despite this, the core functionalities remain similar, ensuring that S3 users can quickly adapt to Greenfield\u2019s environment without significant hurdles.

    Overall, the transition from AWS S3 to Greenfield is facilitated by similar SDK coding practices and metadata management approaches, making it accessible for users familiar with S3 to migrate to Greenfield\u2019s blockchain-based storage solution with minimal learning curve. This compatibility underscores the potential for seamless adaptation, leveraging existing cloud storage knowledge while navigating the nuances of blockchain technology.

    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#attached-code","title":"Attached code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#example-of-greenfield-integration","title":"Example of Greenfield Integration","text":"
    package main\n\nimport (\n    \"bytes\"\n    \"context\"\n    \"fmt\"\n    \"io\"\n    \"log\"\n    \"os\"\n    \"time\"\n\n    \"github.com/bnb-chain/greenfield-go-sdk/client\"\n    \"github.com/bnb-chain/greenfield-go-sdk/types\"\n)\n\n// The config information is consistent with the testnet of greenfield\n// You need to set the privateKey, bucketName, objectName and groupName to make the basic examples work well\nconst (\n    RpcAddr         = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n    ChainId         = \"greenfield_5600-1\"\n    PrivateKey      = \"mock-private-key\"\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"api.js\"\n    UploadObjectKey = \"test-api.js\"\n    DownloadPath    = \"/Users/Desktop/s3test/\"\n    UploadPath      = \"/Users/Desktop/s3test/\"\n)\n\nfunc main() {\n    cli, primarySP, err := NewFromConfig(ChainId, RpcAddr, PrivateKey)\n    handleErr(err, \"NewFromConfig\")\n\n    // create bucket\n    _, err = cli.CreateBucket(context.TODO(), BucketName, primarySP, types.CreateBucketOptions{})\n    handleErr(err, \"CreateBucket\")\n\n    // list buckets\n    bucketsList, err := cli.ListBuckets(context.TODO(), types.ListBucketsOptions {\n        ShowRemovedBucket: false,\n    })\n    handleErr(err, \"ListBuckets\")\n    for _, bucket := range bucketsList.Buckets {\n        fmt.Printf(\"* %s\\n\", bucket.BucketInfo.BucketName)\n    }\n\n    // create object\n    file, err := os.Open(UploadPath + UploadObjectKey)\n    handleErr(err, \"PutObject\")\n    defer file.Close()\n\n    fileInfo, err := file.Stat()\n    handleErr(err, \"Stat\")\n\n    // create object\n    txnHash, err := cli.CreateObject(context.TODO(), BucketName, UploadObjectKey, file, types.CreateObjectOptions{})\n    handleErr(err, \"CreateObject\")\n\n    var buf bytes.Buffer\n    _, err = io.Copy(&buf, file)\n\n    // put object\n    err = cli.PutObject(context.TODO(), BucketName, UploadObjectKey, int64(fileInfo.Size()),\n    file, types.PutObjectOptions{TxnHash: txnHash})\n    handleErr(err, \"PutObject\")\n\n    // wait for object having been successfully uploaded\n    time.Sleep(10 * time.Second)\n\n    // list objects\n    objects, err := cli.ListObjects(context.TODO(), BucketName, types.ListObjectsOptions {\n        ShowRemovedObject: false, Delimiter: \"\", MaxKeys: 100, SPAddress: \"\",\n    })\n    handleErr(err, \"ListObjects\")\n    for _, obj := range objects.Objects {\n        log.Printf(\"* %s\\n\", obj.ObjectInfo.ObjectName)\n    }\n\n    // get object\n    reader, _, err := cli.GetObject(context.TODO(), BucketName, UploadObjectKey, types.GetObjectOptions{})\n    handleErr(err, \"GetObject\")\n\n    outFile, err := os.Create(DownloadPath + ObjectKey)\n    handleErr(err, \"DownloadObject\")\n    defer outFile.Close()\n\n    _, err = io.Copy(outFile, reader)\n    handleErr(err, \"DownloadObject\")\n}\n\nfunc NewFromConfig(chainID, rpcAddress, privateKeyStr string) (client.IClient, string, error) {\n    account, err := types.NewAccountFromPrivateKey(\"test\", privateKeyStr)\n    if err != nil {\n        log.Fatalf(\"New account from private key error, %v\", err)\n        return nil, \"\", err\n    }\n\n    cli, err := client.New(chainID, rpcAddress, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n        return nil, \"\", err\n    }\n    ctx := context.Background()\n\n    // get storage providers list\n    spLists, err := cli.ListStorageProviders(ctx, true)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n        return nil, \"\", err\n    }\n    // choose the first sp to be the primary SP\n    primarySP := spLists[0].GetOperatorAddress()\n    return cli, primarySP, nil\n}\n\nfunc handleErr(err error, funcName string) {\n    if err != nil {\n        log.Fatalln(\"fail to \" + funcName + \": \" + err.Error())\n    }\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/#example-of-s3-integration","title":"Example of S3 Integration","text":"
    package main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"io\"\n    \"log\"\n    \"os\"\n    \"time\"\n\n    \"github.com/aws/aws-sdk-go-v2/aws\"\n    \"github.com/aws/aws-sdk-go-v2/config\"\n    \"github.com/aws/aws-sdk-go-v2/credentials\"\n    \"github.com/aws/aws-sdk-go-v2/service/s3\"\n)\n\nconst (\n    AWSKey          = \"mock-aws-key\"\n    AWSSecret       = \"mock-aws-secret\"\n    Region          = \"us-east-1\"\n    BucketName      = \"mock-bucket-name\"\n    ObjectKey       = \"mock-object-name\"\n    UploadObjectKey = \"test-api.js\"\n    DownloadPath    = \"/Users/Desktop/s3test/\"\n    UploadPath      = \"/Users/Desktop/s3test/\"\n)\n\nfunc main() {\n    // set up aws s3 config\n    cfg, err := config.LoadDefaultConfig(context.TODO(),\n        config.WithRegion(Region),\n        config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(AWSKey, AWSSecret, \"\")),\n    )\n    handleErr(err, \"LoadDefaultConfig\")\n    client := s3.NewFromConfig(cfg)\n\n    // create bucket\n    _, err = client.CreateBucket(context.TODO(), &s3.CreateBucketInput {\n        Bucket: aws.String(BucketName),\n    })\n    handleErr(err, \"CreateBucket\")\n\n    // list buckets by owner\n    result, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})\n    handleErr(err, \"ListBuckets\")\n    for _, bucket := range result.Buckets {\n        fmt.Printf(\"* %s\\n\", aws.ToString(bucket.Name))\n    }\n\n    // create object\n    file, err := os.Open(UploadPath + UploadObjectKey)\n    handleErr(err, \"PutObject\")\n    defer file.Close()\n\n    _, err = client.PutObject(context.TODO(), &s3.PutObjectInput {\n        Bucket: aws.String(BucketName),\n        Key:    aws.String(UploadObjectKey),\n        Body:   file,\n    })\n    handleErr(err, \"PutObject\")\n\n    // wait for object having been successfully uploaded\n    time.Sleep(10 * time.Second)\n    objects, err := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input {\n        Bucket: aws.String(BucketName),\n    })\n    handleErr(err, \"ListObjectsV2\")\n    for _, item := range objects.Contents {\n        fmt.Printf(\"* %s\\n\", aws.ToString(item.Key))\n    }\n\n    // download object\n    resp, err := client.GetObject(context.TODO(), &s3.GetObjectInput {\n        Bucket: aws.String(BucketName),\n        Key:    aws.String(UploadObjectKey),\n    })\n    handleErr(err, \"DownloadObject\")\n\n    defer resp.Body.Close()\n\n    outFile, err := os.Create(DownloadPath + ObjectKey)\n    handleErr(err, \"DownloadObject\")\n\n    defer outFile.Close()\n\n    _, err = io.Copy(outFile, resp.Body)\n    handleErr(err, \"DownloadObject\")\n\n    _, err = client.DeleteObject(context.TODO(), &s3.DeleteObjectInput {\n        Bucket: aws.String(BucketName),\n        Key:    aws.String(ObjectKey),\n    })\n    handleErr(err, \"Delete Object\")\n\n    _, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput {\n        Bucket: aws.String(BucketName),\n    })\n    handleErr(err, \"Delete Bucket\")\n}\n\nfunc handleErr(err error, funcName string) {\n    if err != nil {\n        log.Fatalln(\"fail to \" + funcName + \": \" + err.Error())\n    }\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/","title":"Native Access Control - BNB Greenfield Access Control","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#native-access-control","title":"Native Access Control","text":"

    In this tutorial we\u2019ll use the go-SDK library to manage your buckets and objects.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#prerequisites","title":"Prerequisites","text":"

    Before getting started, you should be familiar with:

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#access-control-features","title":"Access Control Features","text":"Principal Effect Actions Resources Duration Accounts/Groups Allow/Deny UpdateBucketInfo, DeleteBucket, etc Bucket Accounts/Groups Allow/Deny CreateObject,DeleteObject,CopyObject,GetObject,ExecuteObject, etc Object Accounts/Groups Allow/Deny UpdateGroupMember,DeleteGroup, etc Group"},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#setup","title":"Setup","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#create-a-go-project","title":"Create a Go Project","text":"

    Let\u2019s set up a Go project with the necessary dependencies.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#init","title":"Init","text":"
    $ mkdir ~/hellogreenfield\n$ cd ~/hellogreenfield\n$ go mod init hellogreenfield\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#add-sdk-dependencies","title":"Add SDK Dependencies","text":"
    $ go get github.com/bnb-chain/greenfield-go-sdk\n

    Edit go.mod to replace dependencies

    replace (\n    cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9\n    cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9\n    github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2\n    github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1\n    github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3\n    github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1\n    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7\n)\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#install-dependensies","title":"Install dependensies","text":"
    go mod tidy\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#test-a-simple-function","title":"Test a simple function","text":"

    You can refer to the overview to learn about how to create a simple main.go

    If everything is set up correctly, your code will be able to connect to the Greenfield node and return the chain data as shown above.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#account-setup","title":"Account Setup","text":"

    You have to prepare two accounts, one is the principal, which acts like an admimistrator and a member, which will receive the access to view/update objects.

        account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n    if err != nil {\n        log.Fatalf(\"New account from private key error, %v\", err)\n    }\n    cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n    }\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#create-group","title":"Create Group","text":"

    The next step is to create a group, whose member will receive access from the principla account.

      // create group\n  groupTx, err := cli.CreateGroup(ctx, groupName, types.CreateGroupOptions{})\n  handleErr(err, \"CreateGroup\")\n  _, err = cli.WaitForTx(ctx, groupTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n\n  log.Printf(\"create group %s successfully \\n\", groupName)\n\n  // head group info\n  creator, err := cli.GetDefaultAccount()\n  handleErr(err, \"GetDefaultAccount\")\n  groupInfo, err := cli.HeadGroup(ctx, groupName, creator.GetAddress().String())\n  handleErr(err, \"HeadGroup\")\n  log.Println(\"head group info:\", groupInfo.String())\n\n  _, err = sdk.AccAddressFromHexUnsafe(memberAddress)\n  if err != nil {\n    log.Fatalln(\"the group member is invalid\")\n  }\n  // add group member\n  updateTx, err := cli.UpdateGroupMember(ctx, groupName, creator.GetAddress().String(), []string{memberAddress}, []string{},\n    types.UpdateGroupMemberOption{})\n  handleErr(err, \"UpdateGroupMember\")\n  _, err = cli.WaitForTx(ctx, updateTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n\n  log.Printf(\"add group member: %s to group: %s successfully \\n\", memberAddress, groupName)\n\n  // head group member\n  memIsExist := cli.HeadGroupMember(ctx, groupName, creator.GetAddress().String(), memberAddress)\n  if !memIsExist {\n    log.Fatalf(\"head group member %s fail \\n\", memberAddress)\n  }\n\n  log.Printf(\" head member %s exist \\n\", memberAddress)\n

    The result should look something similar to the following:

    2023/10/31 09:34:54 create group sample-group successfully\n2023/10/31 09:34:54 head group info: owner:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" group_name:\"sample-group\" id:\"720\"\n2023/10/31 09:35:01 add group member: 0x843e77D639b6C382e91ef489881963209cB238E5 to group: sample-group successfully\n2023/10/31 09:35:01  head member 0x843e77D639b6C382e91ef489881963209cB238E5 exist\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#create-policy","title":"Create Policy","text":"

    Now, you can let the principal grants the delete bucket, update bucket, delete object, update object access to this group

    // put bucket policy\n    bucketActions := []permTypes.ActionType{\n        permTypes.ACTION_UPDATE_BUCKET_INFO,\n        permTypes.ACTION_DELETE_BUCKET,\n        permTypes.ACTION_DELETE_OBJECT,\n        permTypes.ACTION_GET_OBJECT,\n    }\n    ctx := context.Background()\n    statements := utils.NewStatement(bucketActions, permTypes.EFFECT_ALLOW, nil, types.NewStatementOptions{})\n\n    policyTx, err := cli.PutBucketPolicy(ctx, bucketName, principalStr, []*permTypes.Statement{&statements},\n        types.PutPolicyOption{})\n    handleErr(err, \"PutBucketPolicy\")\n    _, err = cli.WaitForTx(ctx, policyTx)\n    if err != nil {\n        log.Fatalln(\"txn fail\")\n    }\n    log.Printf(\"put bucket %s policy sucessfully, principal is: %s.\\n\", bucketName, principal)\n

    After you run the code, the result should look something similar to the following:

    2023/10/31 10:46:55 put bucket sdkexamplebucket policy sucessfully, principal is:\n2023/10/31 10:46:55 bucket: sdkexamplebucket policy info:id:\"2358\" principal:<type:PRINCIPAL_TYPE_GNFD_ACCOUNT value:\"0x843e77D639b6C382e91ef489881963209cB238E5\" > resource_type:RESOURCE_TYPE_BUCKET resource_id:\"429\" statements:<effect:EFFECT_ALLOW actions:ACTION_UPDATE_BUCKET_INFO actions:ACTION_DELETE_BUCKET actions:ACTION_DELETE_OBJECT actions:ACTION_GET_OBJECT >\n
    You can also inspect using the block scanner, e.g. https://greenfieldscan.com."},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#verify-policy","title":"Verify Policy","text":"

    Here is an example to verify the policy metadata onchain:

    // get bucket policy\n  policyInfo, err := cli.GetBucketPolicy(ctx, bucketName, memberAddress)\n  handleErr(err, \"GetBucketPolicy\")\n  log.Printf(\"bucket: %s policy info:%s\\n\", bucketName, policyInfo.String())\n\n  // verify permission\n  effect, err := cli.IsBucketPermissionAllowed(ctx, memberAddress, bucketName, permTypes.ACTION_DELETE_BUCKET)\n  handleErr(err, \"IsBucketPermissionAllowed\")\n\n  if effect != permTypes.EFFECT_ALLOW {\n    log.Fatalln(\"permission not allowed to:\", principalStr)\n  }\n

    If the policy is recorded as expected, you will not see any error.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#delete-policy","title":"Delete Policy","text":"

    Here is an example to delete your bucket policy.

    The principalStr can be generated by NewPrincipalWithAccount or NewPrincipalWithGroupId method.

        // delete bucket policy\n    policyTx, err = cli.DeleteBucketPolicy(ctx, bucketName, principalStr, types.DeletePolicyOption{})\n    handleErr(err, \"DeleteBucketPolicy\")\n    _, err = cli.WaitForTx(ctx, policyTx)\n    if err != nil {\n        log.Fatalln(\"txn fail\")\n    }\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/access-control/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/","title":"Access Control Management with CLI - BNB Greenfield Access Control","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#access-control-management-with-cli","title":"Access Control Management with CLI","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#background","title":"Background","text":"

    In our last tutorial, we have guided you through the process of setting up your environment, installing the necessary tools, and effectively backing up your files to BNB Greenfield, leveraging the benefits of decentralized storage while ensuring data security and ownership.

    To dive furthur into advanced concepts of Greenfield, we will cover how to handle objects access control with the CLI tool, manage your groups and polocoes.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#verifying-the-environment","title":"Verifying the Environment","text":"

    Please refer to this doc to make sure you have completed installation of gnfd-cmd and setting up your accounts.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#query-bucket-info","title":"Query Bucket Info","text":"

    To query the bucket, execute:

    ./gnfd-cmd bucket head gnfd://website-bucket\n

    You should be able to see

    latest bucket info:\nowner:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"\nbucket_name:\"website-bucket\"\nvisibility:VISIBILITY_TYPE_PRIVATE\nid:\"3101\"\ncreate_at:2023-10-31 01:17:15\npayment_address:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\"\nglobal_virtual_group_family_id:40\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#access-control-management-workflow-with-group","title":"Access Control Management Workflow with Group","text":"

    To manage how users can access your files, you have to follow this process: 1. Set Principle Address which has the administrator role 2. Customize groups members 3. Customize access policy, which may depends on different circustances 4. Bind/unbind policy with group

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#group-operations","title":"Group Operations","text":"

    The group commands is used to create group, update group members, delete group and query group info.

    To create a group one need to call the following storage create group command with the desired group name.

    // create group\ngnfd-cmd group create gnfd://website-group\n

    The operation will submit a transaction to BNB Greenfield blockchain to write the associated metadata. The result should look something similar to the following:

    make_group: gnfd://website-group\ntransaction hash: A1FD3A0E2A337716C344392B840DCC8E804553AF42504FBD6F4C46B9C5B8FAF9\ngroup id: 712\n

    As you can see, the result returns a transaction hash, which one can inspect using the block scanner, e.g. https://greenfieldscan.com. Going to https://testnet.greenfieldscan.com/tx/A1FD3A0E2A337716C344392B840DCC8E804553AF42504FBD6F4C46B9C5B8FAF9, will show all the details of the transaction.

    Add a new member to the group

    // update group member\ngnfd-cmd group update --addMembers 0x843e77D639b6C382e91ef489881963209cB238E5 gnfd://website-group\n

    To verify the new member is indeed part of the group

    // head group member\ngnfd-cmd group head-member  0x843e77D639b6C382e91ef489881963209cB238E5 website-group\n

    The result should look something similar to the following:

    the user 0x843e77D639b6C382e91ef489881963209cB238E5 is a member of the group: gnfd://website-group\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#policy-operations","title":"Policy Operations","text":"

    The gnfd-cmd policy command supports the policy for put/delete resources policy(including objects, buckets, and groups) to the principal.

    The principal is need to be set by --grantee which indicates a greenfield account or --groupId which indicates group id.

    The object policy action can be \u201ccreate\u201d, \u201cdelete\u201d, \u201ccopy\u201d, \u201cget\u201d , \u201cexecute\u201d, \u201clist\u201d or \u201call\u201d. The bucket policy actions can be \u201cupdate\u201d, \u201cdelete\u201d, \u201ccreate\u201d, \u201clist\u201d, \u201cupdate\u201d, \u201cgetObj\u201d, \u201ccreateObj\u201d and so on. The group policy actions can be \u201cupdate\u201d, \u201cdelete\u201d or all, update indicates the update-group-member action.

    In this example, the principal grants the delete bucket, update bucket access to this group

    // grant bucket operation permissions to a group\ngnfd-cmd policy put --groupId 712 --actions delete,update,createObj,getObj grn:b::website-bucket\n

    The result should look something similar to the following:

    put policy of the bucket:website-bucket succ, txn hash: 63735FBF6BDFF95AEED9B8BC8D794474431C77E7EBF768BFAA9E3F7CFB25FF97\nlatest bucket policy info:\n id:\"2316\" principal:<type:PRINCIPAL_TYPE_GNFD_GROUP value:\"172\" > resource_type:RESOURCE_TYPE_BUCKET resource_id:\"3101\" statements:<effect:EFFECT_ALLOW actions:ACTION_DELETE_BUCKET actions:ACTION_UPDATE_BUCKET_INFO actions:ACTION_CREATE_OBJECT >\n
    As you can see, the result returns a transaction hash, which one can inspect using the block scanner, e.g. https://greenfieldscan.com. Going to https://testnet.greenfieldscan.com/tx/63735FBF6BDFF95AEED9B8BC8D794474431C77E7EBF768BFAA9E3F7CFB25FF97, will show all the details of the put policy transaction.

    Upload a private file with principal account:

    gnfd-cmd object put --contentType \"text/xml\" --visibility private ./website/index.html gnfd://website-bucket/index.html\n

    In this example, the principal grants the delete object, update object access to this group

    // grant object operation permissions to a group\ngnfd-cmd policy put --groupId 712 --actions get,delete grn:o::website-bucket/index.html\n

    The result should look something similar to the following:

    put policy of the object:index.html succ, txn hash: BD2E3F74B2FBD18300B2C313E8F0393426C851EC3A9153F37DFD6CDC10F92FF8\nlatest object policy info:\n id:\"2318\" principal:<type:PRINCIPAL_TYPE_GNFD_GROUP value:\"712\" > resource_type:RESOURCE_TYPE_OBJECT resource_id:\"187293\" statements:<effect:EFFECT_ALLOW actions:ACTION_GET_OBJECT actions:ACTION_DELETE_OBJECT >\n

    To verify the group policy is working, you can try view the private object with account 0x843e77D639b6C382e91ef489881963209cB238E5. 1. Go to explorer and find the detail page of the private object. 2. Click on \u201cPreview\u201d button 3. Unlock your wallet and choose the right address. Then, you should be able to view the html file.

    or you can download the file with gnfd-cmd

    ./gnfd-cmd object get  gnfd://website-bucket/index.html\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#update-access-control-with-group","title":"Update Access Control with Group","text":"

    The command to update a group is very simple.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#remove-a-member-from-group","title":"Remove a member from group:","text":"
    // update group member\ngnfd-cmd group update --removeMembers 0xca807A58caF20B6a4E3eDa3531788179E5bc816b gnfd://groupname\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#add-expiretime-for-membership","title":"Add expiretime for membership","text":"

    You can set the expire timestamp for the newly added member. The default value is no experiation.

    // update group member\ngnfd-cmd group update --removeMembers 0xca807A58caF20B6a4E3eDa3531788179E5bc816b gnfd://groupname --expireTime 1699699763\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#remove-policy","title":"Remove Policy","text":"

    Here is an example to delete a policy * Delete a policy for an adress

    gnfd-cmd policy rm --grantee 0x843e77D639b6C382e91ef489881963209cB238E5 --actions get grn:o::website-bucket/index.html\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/#conclusion","title":"Conclusion","text":"

    Overall, the access control management of Greenfield is very powerful and can be used in many scenarios. It is highly recommended for users to engage in hands-on exploration by trying out different account group management operations and permissioning mechanisms. This will provide a deeper understanding of how BNB Greenfield functions and how to effectively manage and secure data within the decentralized storage system.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/","title":"Cross Chain Access Control by CMD - BNB Greenfield Access Control","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/#cross-chain-access-control-by-cmd","title":"Cross Chain Access Control by CMD","text":"

    In this guide, we will walk you through the process of data permission management using the BSC smart contract as a simple howcase of cross chain program-ability of Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/#prerequisites","title":"Prerequisites","text":"

    Before starting, make sure you have the following tools installed:

    Please follow the readme of the above two repositories to install the tools and configure the environment.

    Ensure you get an account that get funds on both BSC and Greenfield network.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/#steps","title":"Steps","text":"

    In the following example, Account A(0x0fEd1aDD48b497d619EF50160f9135c6E221D5F0, stored in keyA.json) will grant Account B(0x3bD70E10D71C6E882E3C1809d26a310d793646eB, stored in keyB.json) the access to his private file through BSC contract.

    Besides, you can save the password to a file and use -p to specify the password file. For example, gnfd-cmd -p password.txt ....

    Before starting, please make sure you created related accounts by gnfd-cmd account import or gnfd-cmd account new and have the config.toml file in the current directory. Please note that the account should have enough balance before sending transactions to greenfield.

    The content of the config.toml is as follows:

    MainnetTestnet
    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\nchainId = \"greenfield_1017-1\"\n
    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\nchainId = \"greenfield_5600-1\"\n
    1. Prepare environment

      $ export AccountA=0x0fEd1aDD48b497d619EF50160f9135c6E221D5F0\n$ export AccountB=0x3bD70E10D71C6E882E3C1809d26a310d793646eB\n
    2. Create a temporary file story.txt

      $ echo \"this is a fun story\" > story.txt \n
    3. Create a bucket named funbucket.

      $ gnfd-cmd -c config.toml -k keyA.json -p password.txt bucket create gnfd://funbucket\n
    4. Create a private object named story.txt in the bucket funbucket.

      $ gnfd-cmd -c config.toml -k keyA.json -p password.txt object put --contentType \"text/xml\" --visibility private ./story.txt  gnfd://funbucket/story.txt\n
    5. Create a group named fungroup.

      $ gnfd-cmd -c config.toml -k keyA.json -p password.txt group create fungroup\ncreate group: fungroup succ, txn hash:17B6AE2C8D30B6D6EEABEE81DB8B37CF735655E9087CB02DC98EFF1DCA9FBE3A, group id: 136 \n

      The console will return the id of the group, which is 136 in this case.

    6. Bind the group fungroup to the object story.txt.

      ## Example, replace the ${GroupId} with the group id you get in the previous step\n$ export GroupId=136\n$ gnfd-cmd -c config.toml -k keyA.json -p password.txt policy put --groupId ${GroupId} --actions get grn:o::funbucket/story.txt   \n
    7. Mirror the group to BSC network.

      ## Example, replace the ${GroupId} with the group id you get in the previous step\n## 97 is the chainId of BSC testnet\n## 56 is the chainId of BSC mainnet\n\n$ export ChainId=56\n$ gnfd-cmd -c config.toml -k keyA.json -p password.txt group mirror --destChainId ${GroupId} --id ${GroupId} \n
    8. Try to access the file through AccountB.

      ## Example\n$ gnfd-cmd -c config.toml -k keyA.json -p password.txt group head-member --groupOwner ${AccountA}  ${AccountB}  fungroup\nthe user does not exist in the group\n$ gnfd-cmd -c config.toml -k keyB.json -p password.txt object get gnfd://funbucket/story.txt ./story-copy.txt\nrun command error: statusCode 403 : code : AccessDenied  (Message: Access Denied)\n

      It turns out that AccountB is not permitted to access the file, which is expected.

    9. Clone the gnfd-contract repository and install the dependencies.

    10. Grant the access to Account B through the contract.

      MainnetTestnet
      export RPC_MAIN=https://bsc-dataseed.bnbchain.org\n$ forge script foundry-scripts/GroupHub.s.sol:GroupHubScript \\\n--sig \"addMember(address operator, uint256 groupId, address member)\" \\\n${AccountA} ${GroupId} ${AccountB} \\\n-f $RPC_MAIN \\\n--private-key 148748590a8b83dxxxxxxxxxxxxxxxxx \\\n--legacy \\\n--broadcast     \n
      export RPC_TEST=https://bsc-testnet-dataseed.bnbchain.org\n$ forge script foundry-scripts/GroupHub.s.sol:GroupHubScript \\\n--sig \"addMember(address operator, uint256 groupId, address member)\" \\\n${AccountA} ${GroupId} ${AccountB} \\\n-f $RPC_TEST\\\n--private-key 148748590a8b83dxxxxxxxxxxxxxxxxx \\\n--legacy \\\n--broadcast\n
    11. Wait 30 seconds, and try to access the file through AccountB again.

      ## Example\n$ gnfd-cmd -c config.toml -k keyA.json -p password.txt group head-member --groupOwner ${AccountA}  ${AccountB} fungroup\nthe user is a member of the group\n$ gnfd-cmd -c config.toml -k keyB.json -p password.txt object get gnfd://funbucket/story.txt \ndownload object story.txt successfully, the file path is ./story-copy.txt, content length:20\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/","title":"Cross Chain Access Control by SDK - BNB Greenfield Access Control","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#cross-chain-access-control-by-sdk","title":"Cross Chain Access Control by SDK","text":"

    In this tutorial we\u2019ll use the go-SDK library to transfer control over objects to the smart contract on BSC and allowing on-chain management. Object mirroring enables greater flexibility and control over decentralized storage on BNB Greenfield to all dApps on BSC. It leverages the capabilities of the BSC and its smart contract functionality to provide enhanced functionality and interoperability between the two platforms.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#prerequisites","title":"Prerequisites","text":"

    Before getting started, you should be familiar with:

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#cross-chain-mechanism","title":"Cross Chain Mechanism","text":"

    Cross-chain communication serves as the foundation for enabling the exchange of assets, data, and functionalities across disparate blockchains, facilitating a more connected and efficient decentralised ecosystem.

    Cross-communication between BNB Greenfield and BSC stands apart from the approaches taken by Polkadot, Chainlink, and Cosmos in several significant aspects.

    Cross chain communication features BNB Greenfield/BSC Cosmos/IBC Polkadot Chainlink CCIP Bulk messaging Custom and performant General application General application General application Compatibility Fully compatible with EVM and Ethereum L2s Only Cosmos ecosystem Only Polkadot ecosystem Specific implementations for each blockchain Security Model Own validators Shared Shared Own validators Tokenomics BNB ATOM DOT LINK Address Scheme Unified - same addresses Can be different addresses Can be different addresses Can be different addresses Composability Shared components with BNB Chain ecosystem Implementation in progress Shared components with Polkadot ecosystem New implementation for each network"},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#account-setup","title":"Account Setup","text":""},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#create-a-go-project","title":"Create a Go Project","text":"

    Let\u2019s set up a Go project with the necessary dependencies.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#init","title":"Init","text":"
    $ mkdir ~/hellogreenfield\n$ cd ~/hellogreenfield\n$ go mod init hellogreenfield\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#add-sdk-dependencies","title":"Add SDK Dependencies","text":"
    $ go get github.com/bnb-chain/greenfield-go-sdk\n

    Edit go.mod to replace dependencies

    replace (\n    cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9\n    cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9\n    github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2\n    github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1\n    github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3\n    github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1\n    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7\n)\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#install-dependensies","title":"Install dependensies","text":"
    go mod tidy\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#test-a-simple-function","title":"Test a simple function","text":"

    You can refer to the overview to learn about how to create a simple main.go

    If everything is set up correctly, your code will be able to connect to the Greenfield node and return the chain data as shown above.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#account-setup_1","title":"Account setup","text":"
    account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n    if err != nil {\n        log.Fatalf(\"New account from private key error, %v\", err)\n    }\n    cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n    if err != nil {\n        log.Fatalf(\"unable to new greenfield client, %v\", err)\n    }\n    ctx := context.Background()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#create-buckets","title":"Create Buckets","text":"

    Now, let\u2019s use the imported account to create a bucket.

    In this example,

        // get storage providers list\n    spLists, err := cli.ListStorageProviders(ctx, true)\n    if err != nil {\n        log.Fatalf(\"fail to list in service sps\")\n    }\n    // choose the first sp to be the primary SP\n    primarySP := spLists[0].GetOperatorAddress()\n\n    bucketName := storageTestUtil.GenRandomBucketName()\n\n    txHash, err := cli.CreateBucket(ctx, bucketName, primarySP, types.CreateBucketOptions{})\n    handleErr(err, \"CreateBucket\")\n    log.Printf(\"create bucket %s on SP: %s successfully \\n\", bucketName, spLists[0].Endpoint)\n\n    waitForTx, _ := cli.WaitForTx(ctx, txHash)\n    log.Printf(\"Wait for tx: %s\", waitForTx.TxResult.String())\n

    The example return message is like the following:

    2023/10/31 13:14:54 create bucket ylatitsb on SP: https://gnfd-testnet-sp1.bnbchain.org successfully\n2023/10/31 13:14:54 Wait for tx: data:\"\\0225\\n+/greenfield.storage.MsgCreateBucketResponse\\022\\006\\n\\0043175\\032\\010\\000\\000\\000\\000\\000\\000\\201\\006\" log:\"[{\\\"msg_index\\\":0,\\\"events\\\":[{\\\"type\\\":\\\"message\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"action\\\",\\\"value\\\":\\\"/greenfield.storage.MsgCreateBucket\\\"},{\\\"key\\\":\\\"sender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"module\\\",\\\"value\\\":\\\"storage\\\"}]},{\\\"type\\\":\\\"greenfield.storage.EventCreateBucket\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"bucket_id\\\",\\\"value\\\":\\\"\\\\\\\"3175\\\\\\\"\\\"},{\\\"key\\\":\\\"bucket_name\\\",\\\"value\\\":\\\"\\\\\\\"ylatitsb\\\\\\\"\\\"},{\\\"key\\\":\\\"charged_read_quota\\\",\\\"value\\\":\\\"\\\\\\\"0\\\\\\\"\\\"},{\\\"key\\\":\\\"create_at\\\",\\\"value\\\":\\\"\\\\\\\"1698779691\\\\\\\"\\\"},{\\\"key\\\":\\\"global_virtual_group_family_id\\\",\\\"value\\\":\\\"40\\\"},{\\\"key\\\":\\\"owner\\\",\\\"value\\\":\\\"\\\\\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\\\\\"\\\"},{\\\"key\\\":\\\"payment_address\\\",\\\"value\\\":\\\"\\\\\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\\\\\"\\\"},{\\\"key\\\":\\\"primary_sp_id\\\",\\\"value\\\":\\\"1\\\"},{\\\"key\\\":\\\"source_type\\\",\\\"value\\\":\\\"\\\\\\\"SOURCE_TYPE_ORIGIN\\\\\\\"\\\"},{\\\"key\\\":\\\"status\\\",\\\"value\\\":\\\"\\\\\\\"BUCKET_STATUS_CREATED\\\\\\\"\\\"},{\\\"key\\\":\\\"visibility\\\",\\\"value\\\":\\\"\\\\\\\"VISIBILITY_TYPE_PRIVATE\\\\\\\"\\\"}]}]}]\" gas_wanted:2400 gas_used:2400 events:<type:\"coin_spent\" attributes:<key:\"spender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"12000000000000BNB\" index:true > > events:<type:\"coin_received\" attributes:<key:\"receiver\" value:\"0xf1829676DB577682E944fc3493d451B67Ff3E29F\" index:true > attributes:<key:\"amount\" value:\"12000000000000BNB\" index:true > > events:<type:\"transfer\" attributes:<key:\"recipient\" value:\"0xf1829676DB577682E944fc3493d451B67Ff3E29F\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"12000000000000BNB\" index:true > > events:<type:\"message\" attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > > events:<type:\"tx\" attributes:<key:\"fee\" value:\"12000000000000BNB\" index:true > attributes:<key:\"fee_payer\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > > events:<type:\"tx\" attributes:<key:\"acc_seq\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd/70\" index:true > > events:<type:\"tx\" attributes:<key:\"signature\" value:\"aKL7wpB1b0107d1OleaHKKBw5mXUskggINbq7hsr90s6MzgV88DxjAGak37xz9V4LsoH0sr7saqBmBrE5MKJtgA=\" index:true > > events:<type:\"message\" attributes:<key:\"action\" value:\"/greenfield.storage.MsgCreateBucket\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"module\" value:\"storage\" index:true > > events:<type:\"greenfield.storage.EventCreateBucket\" attributes:<key:\"bucket_id\" value:\"\\\"3175\\\"\" index:true > attributes:<key:\"bucket_name\" value:\"\\\"ylatitsb\\\"\" index:true > attributes:<key:\"charged_read_quota\" value:\"\\\"0\\\"\" index:true > attributes:<key:\"create_at\" value:\"\\\"1698779691\\\"\" index:true > attributes:<key:\"global_virtual_group_family_id\" value:\"40\" index:true > attributes:<key:\"owner\" value:\"\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"\" index:true > attributes:<key:\"payment_address\" value:\"\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"\" index:true > attributes:<key:\"primary_sp_id\" value:\"1\" index:true > attributes:<key:\"source_type\" value:\"\\\"SOURCE_TYPE_ORIGIN\\\"\" index:true > attributes:<key:\"status\" value:\"\\\"BUCKET_STATUS_CREATED\\\"\" index:true > attributes:<key:\"visibility\" value:\"\\\"VISIBILITY_TYPE_PRIVATE\\\"\" index:true > >\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#create-group","title":"Create Group","text":"

    The next step is to create a group, whose member will receive get object access from the principla account.

      // create group\n  groupTx, err := cli.CreateGroup(ctx, groupName, types.CreateGroupOptions{})\n  handleErr(err, \"CreateGroup\")\n  _, err = cli.WaitForTx(ctx, groupTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n\n  log.Printf(\"create group %s successfully \\n\", groupName)\n\n  // head group info\n  creator, err := cli.GetDefaultAccount()\n  handleErr(err, \"GetDefaultAccount\")\n  groupInfo, err := cli.HeadGroup(ctx, groupName, creator.GetAddress().String())\n  handleErr(err, \"HeadGroup\")\n  log.Println(\"head group info:\", groupInfo.String())\n\n  _, err = sdk.AccAddressFromHexUnsafe(memberAddress)\n  if err != nil {\n    log.Fatalln(\"the group member is invalid\")\n  }\n  // add group member\n  updateTx, err := cli.UpdateGroupMember(ctx, groupName, creator.GetAddress().String(), []string{memberAddress}, []string{},\n    types.UpdateGroupMemberOption{})\n  handleErr(err, \"UpdateGroupMember\")\n  _, err = cli.WaitForTx(ctx, updateTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n\n  log.Printf(\"add group member: %s to group: %s successfully \\n\", memberAddress, groupName)\n\n  // head group member\n  memIsExist := cli.HeadGroupMember(ctx, groupName, creator.GetAddress().String(), memberAddress)\n  if !memIsExist {\n    log.Fatalf(\"head group member %s fail \\n\", memberAddress)\n  }\n\n  log.Printf(\" head member %s exist \\n\", memberAddress)\n

    The result should look something similar to the following:

    2023/10/31 09:34:54 create group sample-group successfully\n2023/10/31 09:34:54 head group info: owner:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" group_name:\"sample-group\" id:\"720\"\n2023/10/31 09:35:01 add group member: 0x843e77D639b6C382e91ef489881963209cB238E5 to group: sample-group successfully\n2023/10/31 09:35:01  head member 0x843e77D639b6C382e91ef489881963209cB238E5 exist\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#create-policy","title":"Create Policy","text":"

    Now, you can let the principal grants the get object access to this group

    // put bucket policy\n    bucketActions := []permTypes.ActionType{\n        permTypes.ACTION_GET_OBJECT,\n    }\n    ctx := context.Background()\n    statements := utils.NewStatement(bucketActions, permTypes.EFFECT_ALLOW, nil, types.NewStatementOptions{})\n\n    policyTx, err := cli.PutBucketPolicy(ctx, bucketName, principalStr, []*permTypes.Statement{&statements},\n        types.PutPolicyOption{})\n    handleErr(err, \"PutBucketPolicy\")\n    _, err = cli.WaitForTx(ctx, policyTx)\n    if err != nil {\n        log.Fatalln(\"txn fail\")\n    }\n    log.Printf(\"put bucket %s policy sucessfully, principal is: %s.\\n\", bucketName, principal)\n

    After you run the code, the result should look something similar to the following:

    2023/10/31 10:46:55 put bucket sdkexamplebucket policy sucessfully, principal is:\n2023/10/31 10:46:55 bucket: sdkexamplebucket policy info:id:\"2358\" principal:<type:PRINCIPAL_TYPE_GNFD_ACCOUNT value:\"0x843e77D639b6C382e91ef489881963209cB238E5\" > resource_type:RESOURCE_TYPE_BUCKET resource_id:\"429\" statements:<effect:EFFECT_ALLOW actions:ACTION_UPDATE_BUCKET_INFO actions:ACTION_DELETE_BUCKET actions:ACTION_DELETE_OBJECT actions:ACTION_GET_OBJECT >\n
    You can also inspect using the block scanner, e.g. https://greenfieldscan.com."},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#mirror-group-to-bsc","title":"Mirror Group to BSC","text":"

    In Greenfield, object mirroring refers to the process of transferring control over objects stored on BNB Greenfield to a smart contract on BNB Smart Chain (BSC)

    This allows the object to be fully managed on-chain on BSC, meaning that users or other smart contracts can perform various operations and changes to the object through on-chain transactions.

    During the mirroring process from BNB Greenfield to BSC, the content of the file itself is not copied. This means that neither the data nor the file metadata, which is stored on the BNB Greenfield blockchain, is transferred to BSC.

        //head group\n    groupInfo, err := cli.HeadGroup(ctx, groupName, creator.GetAddress().String())\n    handleErr(err, \"HeadGroup\")\n    log.Println(\"head group info:\", groupInfo.String())\n\n    // mirror bucket\n    txResp, err := cli.MirrorGroup(ctx, sdk.ChainID(crossChainDestBsChainId), groupInfo.Id, groupName, gnfdSdkTypes.TxOption{})\n    handleErr(err, \"MirrorGroup\")\n    waitForTx, _ = cli.WaitForTx(ctx, txResp.TxHash)\n    log.Printf(\"Wait for tx: %s\", waitForTx.TxResult.String())\n    log.Printf(\"successfully mirrored group wiht  id %s to BSC\", groupInfo.Id)\n
    2023/10/31 21:43:57 group: sdkexamplegroup policy info:id:\"712\" principal:<type:PRINCIPAL_TYPE_GNFD_ACCOUNT value:\"0x843e77D639b6C382e91ef489881963209cB238E5\" > resource_type:RESOURCE_TYPE_BUCKET resource_id:\"429\" statements:<effect:EFFECT_ALLOW actions:ACTION_GET_OBJECT >\n2023/10/31 21:43:57 bucket info: owner:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" bucket_name:\"ylatitsb\" visibility:VISIBILITY_TYPE_PRIVATE id:\"3175\" create_at:1698779691 payment_address:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" global_virtual_group_family_id:40\n

    You can also inspect using the block scanner, e.g. https://greenfieldscan.com.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#access-control-management-on-bsc","title":"Access Control Management on BSC","text":"

    Now you have mirrored your group to BSC and there is an ERCC-721 token minted. At present, the NFTs are not transferable. The group membership can be directly managed by smart contracts on BSC. These operations will directly affect the storage format, access permissions, and other aspects of the data on greenfield with the help of Greenfield Contract.

    First, you have to install the dependencies and setup environment by following the guides.

    Once it\u2019s all set, you can run the following script to add member to your group:

    # set your private-key, operator address, group id, and member address\nforge script foundry-scripts/GroupHub.s.sol:GroupHubScript \\\n--private-key ${your private key} \\\n--sig \"addMember(address operator, uint256 groupId, address member)\" \\\n${the owner of the group} ${your group id} ${the member address to add} \\\n-f https://data-seed-prebsc-1-s1.binance.org:8545/ \\\n--legacy --ffi --broadcast\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#conclusion","title":"Conclusion","text":"

    The Greenfield Blockchain provides a comprehensive set of resources that can be mirrored on the BNB Smart Chain (BSC). This includes buckets, objects, and groups, which can be stored and managed on the BSC as non-fungible tokens (NFTs) conforming to the ERC-721 standard. This integration between Greenfield Blockchain and BNB Smart Chain allows for greater flexibility and accessibility when it comes to accessing and manipulating data, ultimately leading to a more streamlined and efficient data management process.

    "},{"location":"bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/data-marketplace/","title":"MindPress Data Marketplace Introduction - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/data-marketplace/#mindpress-data-marketplace-introduction","title":"MindPress Data Marketplace Introduction","text":"1. Overview

    MindPress Data Marketplace is a demo built on the BNB Smart Chain and BNB Greenfield storage chains. It uses the image trading scenario as an example to demonstrate the use of BNB Greenfield\u2019s latest release (V1.6&V1.7), such as cross-chain programmability, delegate upload, and sponsor-paid storage fees. With these features, developers can easily create a web3 decentralized trading platform based on the BNB Chain ecosystem with a great user experience and comprehensive functions such as storage, trading, and content permission management, thereby accelerating project development and marketing.

    2. Features

    As an image stock, sellers can upload and list photos for sale, while buyers can search for images they like, buy, and download the original files.

    Seller

    Buyer

    3. Benefits after Greenfield V1.6&1.7 updates # Before After Code Related Greenfield Features Network Switch \u274cUsers have to switch between BNB Greenfield and BNB Smart Chain to upload objects and make the trading operation. \u2705No network switch: Users can finish all the operations on BSC network. https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/417 Payment Method \u274cUsers have to pay the storage fee and download quota fee by themselves. \u2705Flexible payment method: Projects can choose to pay storage and download quota fees by themselves, allowing users to use this platform for free and lowering the user threshold, thereby expanding the number of users and facilitating promotion. https://github.com/bnb-chain/greenfield/pull/582 Upload Objects \u274cUsers must upload objects to DCellar before returning to MindPress to list them because the upload process is quite complex to embed in MindPress. \u2705Easy to upload: Users can upload multiple large objects in MindPress at once without requiring a signature or incurring fees because the upload process is greatly simplified by the delegate upload feature. https://github.com/bnb-chain/greenfield/pull/581 List Objects \u274cUsers have to execute 2-3 transactions to complete the list workflow, which also requires switching networks back and forth. \u2705Easy to list: Users need only 2 transactions to complete the list operation to start selling. https://github.com/bnb-chain/greenfield-contracts/pull/140 4. Demo Video 4.1 Buyer workflow Search and filter Buy Images 4.2 Seller Workflow Upload Images List Images Delist Images 5. Environment Support 6. Technical Design 6.1 Overview

    The BNB Greenfield offers resources such as buckets, objects, and groups that can be mirrored on the BNB Smart Chain (BSC) as non-fungible tokens (NFTs) following the ERC-721 standard. Buckets store objects, the basic units with data and metadata. Groups consist of accounts with similar permissions. These resources, including group members\u2019 permissions as ERC-1155 tokens, can be mirrored on the BSC.

    Smart contracts on BSC can directly control mirrored resources, affecting storage formats, access permissions, and other data aspects on Greenfield. This integration boosts flexibility and accessibility, streamlining data management on both platforms. For more on mirroring implementation, refer to this document.

    In the context of the MindPress Data Marketplace, users have the ability to store images on the Greenfield network and sell them on the BSC. Let\u2019s take the example of Alice selling a picture of a carrot on MindPress. To sell carrot images, Alice needs to follow these steps:

    1. Create a bucket, and upload the carrot image to this bucket on BNB Greenfield.
    2. Create a group and grant this group permission to view the carrot image.
    3. List the group on the MindPress Data Marketplace smart contract to sell access permissions on the BSC network.

    Since the carrot image is private, Bob will be denied access to it by default.

    Bob needs to buy permission to join the group. After becoming a member, he can view/download the carrot image.

    6.2 Architecture 6.2.1 Greenfield Cross Chain Design

    The true strength of the Greenfield ecosystem resides in its cutting-edge platform engineered not just for data storage, but also for fostering value creation from data assets and its associated economy. To empower data on Greenfield more effectively, a robust cross-chain mechanism has been introduced, enabling versatile cross-chain programming capabilities.

    The first layer is the Cross-Chain Communication Layer, which is responsible for handling and verifying the communication packages between BSC and BNB Greenfield.

    The second layer is the Resource Mirror Layer, which handles the resource assets defined on BNB Greenfield and mirrors them onto BSC.

    The top layer of the cross-chain system is the Application Layer. This layer consists of smart contracts that are developed by the community on BSC, enabling them to operate the mirrored resource entities on the Resource Mirror Layer.

    6.2.2 MindPress Workflow

    MindPress Data Marketplace is built on the cross-chain mechanism of BNB Greenfield and BSC, enabling users to flexibly manipulate data stored on Greenfield on the BSC side, facilitating data circulation and value creation. Below, we delve into the technical principles of the key processes involved in MindPress.

    The MindPress contract will do the following operations:

    1. help the user to create a bucket to store the uploaded images and the paymaster of the bucket is set to mindpress contract.
    2. set the flow rate limit for the bucket to give the initial free charge.

    Users should go through the following 2 transactions to list an object:

    1. Send a list request to the MindPress contract with the object ID, group name and price, MindPress will create a new group where all members of the group have access to the object.
    2. Send a cross-chain put-policy transaction to bind the object and the created group.

    6.3 Technical Considerations 7. Getting Started

    MindPress consists of three engineering projects:

    8. Contributing

    Thank you for considering using and contributing to MindPress! We welcome developers to utilize our open-source codebase and encourage collaboration to improve and extend its functionality. If you have any questions, feel free to reach out to us for assistance. Happy coding!

    9. License

    The library is licensed under the GNU Lesser General Public License v3.0, also included in our repository in the LICENSE file.

    10. Disclaimer

    The software and related documentation are under active development, all subject to potential future change without notification and not ready for production use. The code and security audit have not been fully completed and are not ready for any bug bounty. We advise you to be careful and experiment on the network at your own risk. Stay safe out there.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/","title":"Overview - BNB Greenfield App","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#overview","title":"Overview","text":"

    Native apps are applications developed only using the Greenfield SDK, without involving the development of smart contracts.

    In the following sections, we will delve deeper into each native application, providing step-by-step guides, code snippets, and best practices to empower you to create powerful and innovative dApps without the need for smart contract development.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#data-marketplace","title":"Data Marketplace","text":"

    Data marketplace is a data exchange platform where users can freely create, list, trade, and sell data assets, including digital publications, scientific experimental data, and specific domain data.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#demo-link","title":"Demo Link","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#source-code","title":"Source Code","text":"

    MindPress consists of three engineering projects:

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#developing-with-smart-contracts-on-bsc","title":"Developing with smart contracts on BSC","text":"

    One of the primary methods for building dApps with BNB Greenfield is by deploying smart contracts to the BSC. Smart contracts are self-executing programs that facilitate and enforce the execution of agreements without the need for intermediaries.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#cli","title":"CLI","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/overview/#sdk-demo","title":"SDK Demo","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/","title":"Simple Tool for File Management - BNB Greenfield File Management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#building-file-management-tool-with-greenfield-sdk","title":"Building File Management Tool with Greenfield SDK","text":"

    Several Chain API libraries are available. These libraries manage the low-level logic of connecting to Greenfield node, making requests, and handing the responses. * go-sdk * js-sdk

    In this tutorial we\u2019ll use the go-SDK library to interact with testnet.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#prerequisites","title":"Prerequisites","text":"

    Before getting started, you should be familiar with: * Greenfield basics * Greenfield command line examples

    Also, make sure you have the following dependencies installed with the latest version: * Go version above 1.20

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#go-sdk-features","title":"Go-SDK Features","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#setup","title":"Setup","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#create-a-go-project","title":"Create a Go Project","text":"

    Let\u2019s set up a Go project with the necessary dependencies.

    Init

    $ mkdir ~/hellogreenfield\n$ cd ~/hellogreenfield\n$ go mod init hellogreenfield\n

    Add SDK Dependencies

    $ go get github.com/bnb-chain/greenfield-go-sdk\n

    Edit go.mod to replace dependencies

    replace (\n    cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9\n    cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9\n    github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2\n    github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1\n    github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3\n    github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1\n    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7\n)\n

    Install dependensies

    go mod tidy\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#test-a-simple-function","title":"Test a simple function","text":"

    Now we\u2019re ready to connect to Greenfield testnet and interact with the storage provider APIs. Let\u2019s write a simple script to query the Greenfield version to verify if everything works as expected.

    Create a main.go file in your project and add the following code.

    package main\n\nimport (\n  \"context\"\n  \"log\"\n\n  \"github.com/bnb-chain/greenfield-go-sdk/client\"\n  \"github.com/bnb-chain/greenfield-go-sdk/types\"\n)\n\nconst (\n  rpcAddr    = \"https://greenfield-chain.bnbchain.org:443\"\n  chainId    = \"greenfield_1017-1\"\n  /*testnet\n  rpcAddr    = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n  chainId    = \"greenfield_5600-1\"\n  */\n  privateKey = \"\"\n)\n\nfunc main() {\n  account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n  if err != nil {\n    log.Fatalf(\"New account from private key error, %v\", err)\n  }\n\n  cli, err := client.New(chainId, rpcAddr, client.Option{DefaultAccount: account})\n  if err != nil {\n    log.Fatalf(\"unable to new greenfield client, %v\", err)\n  }\n\n  ctx := context.Background()\n  nodeInfo, versionInfo, err := cli.GetNodeInfo(ctx)\n  if err != nil {\n    log.Fatalf(\"unable to get node info, %v\", err)\n  }\n\n  log.Printf(\"nodeInfo moniker: %s, go version: %s\", nodeInfo.Moniker, versionInfo.GoVersion)\n  latestBlock, err := cli.GetLatestBlock(ctx)\n  if err != nil {\n    log.Fatalf(\"unable to get latest block, %v\", err)\n  }\n  log.Printf(\"latestBlock header: %s\", latestBlock.Header)\n\n  heightBefore := latestBlock.Header.Height\n  log.Printf(\"Wait for block height: %d\", heightBefore)\n  err = cli.WaitForBlockHeight(ctx, heightBefore+10)\n  if err != nil {\n    log.Fatalf(\"unable to wait for block height, %v\", err)\n  }\n  height, err := cli.GetLatestBlockHeight(ctx)\n  if err != nil {\n    log.Fatalf(\"unable to get latest block height, %v\", err)\n  }\n\n  log.Printf(\"Current block height: %d\", height)\n}\n

    Run the following command in your project directory:

    go run main.go\n
    This will output something like:
    2023/09/12 22:18:10 nodeInfo moniker: fullnode, go version: go version go1.20.7 linux/amd64\n2023/09/12 22:18:10 latestBlock header: {{%!s(uint64=11) %!s(uint64=0)} greenfield_5600-1 %!s(int64=401149) 2023-09-13 04:18:05.661693468 +0000 UTC\n{\n    \"header\": {\n      \"version\": {\n        \"block\": \"11\",\n        \"app\": \"0\"\n      },\n      \"chain_id\": \"greenfield_5600-1\",\n      \"height\": \"401149\",\n      \"time\": \"2023-09-13T04:18:05.661693468Z\",\n      \"last_block_id\": {\n        \"hash\": \"KenBGYDrtA7Bnyy6j3R3d16GWuHnIl5gJW0J3kmM4r8=\",\n        \"part_set_header\": {\n          \"total\": 1,\n          \"hash\": \"W6nmeVJEhHinvI4I6HBsU/A87Zma8DVVvddBATJdctE=\"\n        }\n      },\n      \"last_commit_hash\": \"/G92Jzr8fPpqKY89F3xa3dytOF8a2HLvqCrccm9scXM=\",\n      \"data_hash\": \"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\",\n      \"validators_hash\": \"FykCd/548F1J28ssZr71B1805hzxENaQvexsW/Dxo3E=\",\n      \"next_validators_hash\": \"FykCd/548F1J28ssZr71B1805hzxENaQvexsW/Dxo3E=\",\n      \"consensus_hash\": \"FgA8CM0pWCco2OYq8pA9tuklVX8bmHmMV2Ssdj31W4E=\",\n      \"app_hash\": \"wv+XqXhJBQPYpat/Obaj00u86KfJ8le4LIIFFAgqVmA=\",\n      \"last_results_hash\": \"f6XeDeH8QasoTSGpSJL0r2WGE4MlrXOVt0cE3bIQE8I=\",\n      \"evidence_hash\": \"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\",\n      \"proposer_address\": \"KhlQ9bz1O8iaWZnqKe36m3IpcP4=\",\n      \"randao_mix\": \"/6zQmCJztTeqZIRHe/pXxhgSbfwDLE85awoa4c8sShUUwGGLqFyshMag63MTB7JC2fAsUqPg1ryALY+uQNZ3Bw==\"\n    }\n}\n2023/09/12 22:18:10 Wait for block height: 401149\n2023/09/12 22:18:34 Current block height: 401159\n
    If everything is set up correctly, your code will be able to connect to the Greenfield node and return the chain data as shown above."},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#get-chain-data","title":"Get Chain Data","text":"

    In the previous step, we created a main.go file to demonstrate the basic steps to connect to the node and initialize a Client to query chain data. Next, let\u2019s use some more functions. Get current chain head: We can add the following code in main.go to query current head of the chain.

      blockByHeight, err := cli.GetBlockByHeight(ctx, height)\n  if err != nil {\n    log.Fatalf(\"unable to get block by height, %v\", err)\n  }\n  log.Printf(\"Current block height: %d\", blockByHeight.Header)\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#get-address-balance","title":"Get Address balance","text":"

    With a given greenfield wallet address, you can query its balance by calling GetAccountBalance function.

      balance, err := cli.GetAccountBalance(ctx, account.GetAddress().String())\n  if err != nil {\n    log.Fatalf(\"unable to get balance, %v\", err)\n  }\n  log.Printf(\"%s Current balance: %s\", account.GetAddress().String(), balance.String())\n

    Apart from the basic data queries shown above, there are many more features. Please see the JSON-RPC API Reference for all Greenfield API definitions.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#manage-wallet","title":"Manage Wallet","text":"

    Greenfield wallets hold addresses that you can use to manage objects, sign transactions, and pay for gas fees. In this section, we will demonstrate different ways to manage your wallet. 1. First, let\u2019s make sure your connected node is running and the wallet address contains some testnet BNB. 2. Create a new file called account.go in the same project as earlier. This is where we\u2019ll write all out wallet-related code. 3. In account.go import modules and initialize your private key or mnemonic phrase.

      //import mnemonic\n  account, err := types.NewAccountFromMnemonic(\"test\", mnemonic)\n  //import private key\n  account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n

    Let\u2019s create a second wallet address so we can test transfers. The new address will be created locally and start with 0 token balance:

      account2, _, err := types.NewAccount(\"test2\")\n

    Now, let\u2019s try to transfer tBNB to this new address. Under the hood, this will create a transaction to transfer tBNB from fromAddress to toAddress, sign the transaction using SDK, and send the signed transaction to the Greenfield node.

        transferTxHash, err := cli.Transfer(ctx, account2.GetAddress().String(), math.NewIntFromUint64(10000000000), types2.TxOption{})\n   if err != nil {\n    log.Fatalf(\"unable to send, %v\", err)\n   }\n   log.Printf(\"Transfer response: %s\", transferTxHash)\n\n   waitForTx, err := cli.WaitForTx(ctx, transferTxHash)\n\n   log.Printf(\"Wair for tx: %s\", waitForTx.TxResult.String())\n\n   balance, err = cli.GetAccountBalance(ctx, account2.GetAddress().String())\n ```\n\nRun the code to test the transfer of tBNB:\n```sh\ngo run account.go\n

    This will output something like:

    2023/09/07 11:18:51 Wair for tx: data:\"\\022&\\n$/cosmos.bank.v1beta1.MsgSendResponse\\032\\010\\000\\000\\000\\000\\000\\000\\372\\235\" log:\"[{\\\"msg_index\\\":0,\\\"events\\\":[{\\\"type\\\":\\\"message\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"action\\\",\\\"value\\\":\\\"/cosmos.bank.v1beta1.MsgSend\\\"},{\\\"key\\\":\\\"sender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"module\\\",\\\"value\\\":\\\"bank\\\"}]},{\\\"type\\\":\\\"coin_spent\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"spender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"amount\\\",\\\"value\\\":\\\"10000000000BNB\\\"}]},{\\\"type\\\":\\\"coin_received\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"receiver\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"amount\\\",\\\"value\\\":\\\"10000000000BNB\\\"}]},{\\\"type\\\":\\\"transfer\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"recipient\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"sender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"},{\\\"key\\\":\\\"amount\\\",\\\"value\\\":\\\"10000000000BNB\\\"}]},{\\\"type\\\":\\\"message\\\",\\\"attributes\\\":[{\\\"key\\\":\\\"sender\\\",\\\"value\\\":\\\"0x525482AB3922230e4D73079890dC905dCc3D37cd\\\"}]}]}]\" gas_wanted:1200 gas_used:1200 events:<type:\"coin_spent\" attributes:<key:\"spender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"6000000000000BNB\" index:true > > events:<type:\"coin_received\" attributes:<key:\"receiver\" value:\"0xf1829676DB577682E944fc3493d451B67Ff3E29F\" index:true > attributes:<key:\"amount\" value:\"6000000000000BNB\" index:true > > events:<type:\"transfer\" attributes:<key:\"recipient\" value:\"0xf1829676DB577682E944fc3493d451B67Ff3E29F\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"6000000000000BNB\" index:true > > events:<type:\"message\" attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > > events:<type:\"tx\" attributes:<key:\"fee\" value:\"6000000000000BNB\" index:true > attributes:<key:\"fee_payer\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > > events:<type:\"tx\" attributes:<key:\"acc_seq\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd/0\" index:true > > events:<type:\"tx\" attributes:<key:\"signature\" value:\"plUsfX6lsI0PLjPfFRY7RvYafQ9GK4gAh3pZHddcMdsR9wJRgKUVJ/JDy4HrIEI+qYHP1bGUOxWExmsVdab0xwE=\" index:true > > events:<type:\"message\" attributes:<key:\"action\" value:\"/cosmos.bank.v1beta1.MsgSend\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"module\" value:\"bank\" index:true > > events:<type:\"coin_spent\" attributes:<key:\"spender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"10000000000BNB\" index:true > > events:<type:\"coin_received\" attributes:<key:\"receiver\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"10000000000BNB\" index:true > > events:<type:\"transfer\" attributes:<key:\"recipient\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > attributes:<key:\"amount\" value:\"10000000000BNB\" index:true > > events:<type:\"message\" attributes:<key:\"sender\" value:\"0x525482AB3922230e4D73079890dC905dCc3D37cd\" index:true > >\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#make-a-storage-deal","title":"Make a storage deal","text":"

    Storing data is one of the most important features of Greenfield. In this section, we\u2019ll walk through the end-to-end process of storing your data on the Greenfield network. We\u2019ll start by importing your data, then make a storage deal with a storage provider, and finally wait for the deal to complete.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#1-create-a-main-file","title":"1. Create a main file","text":"

    Create a storage.go file in your demo project and add the following boilerplate code:

    func main() {\u200b\n  // initialize account\n  account, err := types.NewAccountFromPrivateKey(\"test\", privateKey)\n  log.Println(\"address info:\", account)\u200b\n  if err != nil {\n    log.Fatalf(\"New account from private key error, %v\", err)\n  }\n\n  //initialize client\n  cli, err := client.New(chainId, rpcAddr, client.Option {DefaultAccount: account})\n  if err != nil {\n    log.Fatalf(\"unable to new greenfield client, %v\", err)\n  }\n\n  ctx := context.Background()\u200b\n\n  // 1. choose storage provider\n  // 2. Create a bucket\n  // 3. Upload your data and set a quota      \u200b\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#2-choose-your-own-sp","title":"2. Choose your own SP","text":"

    You can query the list of SP.

      // get storage providers list\n  spLists, err := cli.ListStorageProviders(ctx, true)\n  if err != nil {\n    log.Fatalf(\"fail to list in service sps\")\n  }\n\n  //choose the first sp to be the primary SP\n  primarySP := spLists[0].GetOperatorAddress()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#3-create-your-bucket","title":"3. Create your bucket","text":"

    Bucket can be private or public. You can customize it with options. * VISIBILITY_TYPE_PUBLIC_READ * VISIBILITY_TYPE_PRIVATE

      chargedQuota := uint64(10000000)\n  visibility := storageTypes.VISIBILITY_TYPE_PUBLIC_READ\n  opts := types.CreateBucketOptions{Visibility: visibility, ChargedQuota: chargedQuota}\n\n  bucketTx, err := cli.CreateBucket(ctx, bucketName, primarySP, opts)\n  if err != nil {\n    log.Fatalf(\"unable to send, %v\", err)\n  }\n  log.Printf(\"Create bucket response: %s\", bucketTx)\n
    To understand how does quota work, read this doc."},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#4-upload-your-object","title":"4. Upload your object","text":"

    Objects can also be private or public. Uploading objects is composed of two parts: create and put. * CreateObject gets an approval of creating an object and sends createObject txn to Greenfield network. * PutObject supports the second stage of uploading the object to bucket.

      // create and put object\n  var buffer bytes.Buffer\n  line := `0123456789`\n  for i := 0; i < objectSize/10; i++ {\n    buffer.WriteString(fmt.Sprintf(\"%s\", line))\n  }\n\n  txnHash, err := cli.CreateObject(ctx, bucketName, objectName, bytes.NewReader(buffer.Bytes()), types.CreateObjectOptions{})\n\n  handleErr(err, \"CreateObject\")\n\n  err = cli.PutObject(ctx, bucketName, objectName, int64(buffer.Len()),\n    bytes.NewReader(buffer.Bytes()), types.PutObjectOptions{TxnHash: txnHash})\n  handleErr(err, \"PutObject\")\n\n  log.Printf(\"object: %s has been uploaded to SP\\n\", objectName)\n\n  waitObjectSeal(cli, bucketName, objectName)\n
      func waitObjectSeal(cli client.Client, bucketName, objectName string) {\n    ctx := context.Background()\n    // wait for the object to be sealed\n    timeout := time.After(15 * time.Second)\n    ticker := time.NewTicker(2 * time.Second)\n\n    for {\n      select {\n      case <-timeout:\n        err := errors.New(\"object not sealed after 15 seconds\")\n        handleErr(err, \"HeadObject\")\n      case <-ticker.C:\n        objectDetail, err := cli.HeadObject(ctx, bucketName, objectName)\n        handleErr(err, \"HeadObject\")\n        if objectDetail.ObjectInfo.GetObjectStatus().String() == \"OBJECT_STATUS_SEALED\" {\n          ticker.Stop()\n          fmt.Printf(\"put object %s successfully \\n\", objectName)\n          return\n        }\n      }\n    }\n  }\n

    The primary SP syncs with secondary SPs to set up the data redundancy, and then it signs a Seal transaction with the finalized metadata for storage. If the primary SP determines that it doesn\u2019t want to store the file due to whatever reason, it can also \u201cSealReject\u201d the request.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#5-object-management","title":"5. Object management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#51-read-object","title":"5.1 Read object","text":"

    You can call GetObject function to download data.

      // get object\n  reader, info, err := cli.GetObject(ctx, bucketName, objectName, types.GetObjectOptions{})\n  handleErr(err, \"GetObject\")\n  log.Printf(\"get object %s successfully, size %d \\n\", info.ObjectName, info.Size)\n  handleErr(err, \"GetObject\")\n  objectBytes, err := io.ReadAll(reader)\n  fmt.Printf(\"Read data: %s\\n\", string(objectBytes))\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#52-update-object-visibility","title":"5.2 Update object visibility","text":"
      //update bucket visibility\n  updateBucketTx, err := cli.UpdateBucketVisibility(ctx, bucketName,\n              storageTypes.VISIBILITY_TYPE_PRIVATE, types.UpdateVisibilityOption{})\n\n  resp, err := cli.WaitForTx(ctx, updateBucketTx)\n  fmt.Printf(\"Update response: %s\\n\", resp)\n  handleErr(err, \"UpdateBucketVisibility\")\n\n  // Update object visibility\n  updateObjectTx, err := cli.UpdateObjectVisibility(ctx, bucketName,objectName,\n              storageTypes.VISIBILITY_TYPE_PRIVATE, types.UpdateObjectOption{})\n\n  resp, err := cli.WaitForTx(ctx, updateObjectTx)\n  fmt.Printf(\"Update response: %s\\n\", resp)\n  handleErr(err, \"UpdateObjectVisibility\")\n ```\n\n#### 5.3 Delete object\nThe function DeleteObject support deleting objects.\n```go\n  // delete object\n  delTx, err := cli.DeleteObject(ctx, bucketName, objectName, types.DeleteObjectOption{})\n  handleErr(err, \"DeleteObject\")\n  _, err = cli.WaitForTx(ctx, delTx)\n  if err != nil {\n    log.Fatalln(\"txn fail\")\n  }\n  log.Printf(\"object: %s has been deleted\\n\", objectName)\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#conclusion","title":"Conclusion","text":"

    Congratulations on making it all the way through this tutorial! In this tutorial, we learned the basics of interacting with the Greenfield network using SDK library.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/#source-code","title":"Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/","title":"Dataset Batch operations - BNB Greenfield File Management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#how-does-batch-object-uploading-work-in-greenfield","title":"How does batch object uploading work in Greenfield?","text":"

    In Greenfield, uploading an object to a bucket is a two-stage process. First, a transaction including the object metadata needs to be broadcasted to the Greenfield Chain and confirmed. After confirmation, PUT the object to a Greenfield Storage Provider. In the first stage, every transaction needs to be signed by the primary key(also known as account, refer to accounts for more details). And if you are accessing Greenfield via front-end app and connecting wallet like Metamask(or other compatible wallets), you will be asked for approval to sign the transaction.

    For people who may have encountered the need to upload large amounts of objets, while uploading objects to Greenfield individually can be a time-consuming and tedious process, because they have to repeatedly approve wallet\u2019s pop-up requests to send transactions, batch uploading can be a quick and efficient solution to this problem.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#ways-to-perform-batch-uploading","title":"Ways to Perform Batch Uploading","text":"

    We would introduce two ways to achive the purpose of batch uploading:

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#multi-message","title":"Multi-Message.","text":"

    Greenfield supports supports embedding multiple messages in a single transaction. You can create a transaction with multiple MsgCreateObject messages and broadcast it to the Greenfield Chain. Once the object metadata is confirmed on-chain, you can start PUTting the objects to the Storage Provider. However, please note that this approach may not be suitable for very large batches due to transaction size limitations in Greenfield.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#temporary-account","title":"Temporary Account.","text":"

    Create a temporary account at runtime and grant it full permissions to create objects on behalf of your primary account. In this approach, your primary account only needs to send a transaction to Greenfield to grant permissions to the temporary account. For each object to be uploaded, the temporary account will be used to broadcast the transaction to the Greenfield Chain. There is no further interaction required from the primary account. Please note, the temporary account does not need to be deposited.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#bundle-service","title":"Bundle Service","text":"

    Storing small files in Greenfield is inefficient due to the metadata stored on the blockchain being larger than the files themselves. This leads to higher costs for users. Additionally, Greenfield Blockchain has a capacity limit for processing files simultaneously.

    To address this issue, we have proposed BEP-323: Bundle Format For Greenfield. This repository contains the Golang version of the bundle format, which guides users on aggregating objects into a bundle and parsing a bundled object into separate objects.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#temporary-account-showcase","title":"Temporary Account Showcase","text":"

    To demonstrate the batch uploading process using the Temporary Account approach, an example is provided using the Greenfield-go-sdk. The example includes steps to create a bucket for object storage, generate a temporary account, grant permissions to the temporary account, and create and PUT objects.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#create-a-bucket-for-object-storage","title":"Create a bucket for object storage.","text":"

    Before we get started, we would need to create a bucket to hold objects using the primary account. This requires broadcasting a transaction to Greenfield. The code below shows how to fill in the CreateBucket request with the bucket name and selected Storage Provider that will serve our bucket, after the transaction is sent, you might want to check the bucket\u2019s existence to confirm its creation.

    primaryAccount, _ := types.NewAccountFromPrivateKey(\"primaryAccount\", privateKey)\ncli, _ := client.New(chainId, rpcAddr, client.Option{DefaultAccount: primaryAccount})\nctx := context.Background()\n// get storage providers list\nisInService := true\nspLists, _ := cli.ListStorageProviders(ctx, isInService)\n// choose the first sp to be the primary SP, you are free to choose any other one\nprimarySP := spLists[0].GetOperatorAddress()\n// sends a request to Greenfield to create a bucket.\ncli.CreateBucket(ctx, \"yourBucketName\", primarySP, types.CreateBucketOptions{})\n// wait for confirmation\ntime.Sleep(3 * time.Second)\n// get bucket meta data from Greenfield\nbucketInfo, _ := cli.HeadBucket(ctx, \"yourBucketName\")\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#temporary-account-generation","title":"Temporary account generation","text":"

    Once the bucket is created, we can start generating the temporary account. A private key is 32 bytes represented as a 64 hexadecimal character string. We can create any random 64 hexadecimal character string to form a private key. However, in that case, we won\u2019t be able to recover it and reuse in the future. So, it is more preferred to use a designed payload to generate the private key. In the code snippet below, we concatenate a signPayload by string \u201cpayload\u201d and the account sequence, We then use the signature signed by our primary account to form a newly created private key. The signPayload acts like a password. No matter what manipulation is applied to the signPayload to generate the signature, as long as we remember the signPayload, we can always retrieve the private key by applying the same manipulation again. The example shown here is just one way to get the signature and used for new temporary priavte key, but you are free to use any other algorithm.

    // generate the temp account using user's primary account signing on payload decided by user, here we add the account nonce to be part of sign payload\nsignPayload := fmt.Sprintf(\"payload%d\", primaryAccount.GetSequence())\ntempAcct, _ := genTemporaryAccount(primaryAccount, signPayload)\ntempAcctAddr, _ := tempAcct.GetAddress().Marshal()\n
    // genTemporaryAccount generates a temporary account, the signPayload is to be signed by user's own private key(Primary account),\n// and the signature is used to generate the temporary account's private key.\n// User can reconvert account with the signPayload at any time\nfunc genTemporaryAccount(acct *types.Account, signPayload string) (*types.Account, error) {\n    signBz := []byte(signPayload)\n    sig, err := acct.Sign(tmhash.Sum(signBz))\n    if err != nil {\n    return nil, err\n    }\n    if len(sig) < privateKeyLength {\n    return nil, fmt.Errorf(\"required signature lenght is no less than %d, cur lenght %d\", privateKeyLength, len(sig))\n    }\n    return types.NewAccountFromPrivateKey(\"temp\", hex.EncodeToString(sig[:privateKeyLength]))\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#grant-temporary-account-permissions","title":"Grant temporary account permissions","text":"

    To entitle the temporary account to create objects on behalf of the primary account, two types of permissions are required. Both need to be granted by the primary account: - Grant the creating object permission in the bucket. Policy defines that the operation that can be enforced on a resource by an account or a group. Refer to permission to get more details - Grant an allowance so that the gas fee will be deducted from the primary account, and the primary account will be the owner of objects.

    Again, we would need to broadcast transaction including these two types of granting messages to Greenfield using the primary account.

    // Grant the temporary account creating objects permission in the primary account's bucket\nstatement := &permTypes.Statement{\n    Actions: []permTypes.ActionType{permTypes.ACTION_CREATE_OBJECT},\n    Effect:  permTypes.EFFECT_ALLOW,\n}\nmsgPutPolicy := storageTypes.NewMsgPutPolicy(primaryAccount.GetAddress(), gnfdTypes.NewBucketGRN(\"yourBucketName\").String(), \n    permTypes.NewPrincipalWithAccount(tempAcct.GetAddress()), []*permTypes.Statement{statement}, nil)\n\n// Grant allowance to the temporary account to broadcast the expected transaction type\nallowedMsg := make([]string, 0)\nallowedMsg = append(allowedMsg, \"/greenfield.storage.MsgCreateObject\")\nallowance, _ := feegrant.NewAllowedMsgAllowance(&feegrant.BasicAllowance{}, allowedMsg)\nmsgGrantAllowance, _ := feegrant.NewMsgGrantAllowance(allowance, primaryAccount.GetAddress(), tempAcct.GetAddress())\n\n// Broadcast the transaction to Greenfield\ncli.BroadcastTx(ctx, []sdk.Msg{msgGrantAllowance, msgPutPolicy}, types.TxOption{})\n\n// Wait for a block and confirm that permissions are granted\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#create-object-meta-and-put-object","title":"Create object meta and put object","text":"

    Finally, you can create the object metadata and put the object using the temporary account:

    // Switch to use the temporary account\ncli.SetDefaultAccount(tempAcct)\n// Define the primary account as the granter\ntxOpt := types.TxOption{FeeGranter: primaryAccount.GetAddress()}\n// create object content\nvar buffer bytes.Buffer\nline := `0123456789`\nfor i := 0; i < 100; i++ {\n    buffer.WriteString(fmt.Sprintf(\"%s\", line))\n}\n// Create the object meta on Greenfield Chain\ncli.CreateObject(ctx, \"yourBucketName\", \"yourObjectName\", bytes.NewReader(buffer.Bytes()), types.CreateObjectOptions{TxOpts: &txOpt})\n// Wait for a block, once the meta is created on the chain, upload the object to the Greenfield Storage Provider\ntime.Sleep(3 * time.Second)\n// Upload the object to Greenfield Storage Provider\ncli.PutObject(ctx, \"yourBucketName\", \"yourObjectName\", int64(buffer.Len()), bytes.NewReader(buffer.Bytes()), types.PutObjectOptions{})\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#bundle-service-example","title":"Bundle Service Example","text":"

    Here is the guide for how to aggregate batch objects as a bundle, and how to parse a bundled object. As for how to interact with Greenfield, you should refer to \u3010Greenfield GO SDK](https://github.com/bnb-chain/greenfield-go-sdk).

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#aggregate-various-objects-as-bundle","title":"Aggregate various objects as bundle","text":"

    Follow the steps below to aggregate multiple objects into a single bundle.

    1. Use the NewBundlefunction to create an empty bundle.
    // Assemble above two objects into a bundle object\n    bundle, err := bundle.NewBundle()\n    handleErr(err, \"NewBundle\")\n
    1. Use the bundle\u2019s AppendObject method to add objects to the bundle individually.

          _, err = bundle.AppendObject(\"object1\", bytes.NewReader(buffer1.Bytes()), nil)\n    handleErr(err, \"AppendObject\")\n    _, err = bundle.AppendObject(\"object2\", bytes.NewReader(buffer2.Bytes()), nil)\n    handleErr(err, \"AppendObject\")\n
    2. Use the bundle\u2019s FinalizeBundle method to seal the bundle, preventing any further objects from being added.

          bundledObject, totalSize, err := bundle.FinalizeBundle()\n    handleErr(err, \"FinalizeBundle\")\n
    3. To release resources after use, utilize the Close method of the bundle.

       defer bundle.Close()\n

    Full example here

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/#extract-objects-from-bundled-object","title":"Extract objects from bundled object","text":"

    Follow the steps below to extract various objects from a bundle.

    1. Open the bundled object as a bundle instance using NewBundleFromFile.
      // Extract objects from bundled object\n    bundle, err := bundle.NewBundleFromFile(bundleFile.Name())\n    handleErr(err, \"NewBundleFromFile\")\n
    2. Retrieve all the objects\u2019 meta within the bundle using the bundle\u2019s GetBundleObjectsMeta method.
      // Extract objects from bundled object\n    objMeta, err := bundle.GetBundleObjectsMeta(bundleFile.Name())\n    handleErr(err, \"GetBundleObjectsMeta\")\n
    3. Access various objects one by one using the bundle\u2019s GetObject method.

          obj1, size, err := bundle.GetObject(\"object1\")\n    if err != nil || obj1 == nil || size != singleObjectSize {\n        handleErr(fmt.Errorf(\"parse object1 in bundled object failed: %v\", err), \"GetObject\")\n    }\n    obj2, size, err := bundle.GetObject(\"object2\")\n    if err != nil || obj2 == nil || size != singleObjectSize {\n        handleErr(fmt.Errorf(\"parse object2 in bundled object failed: %v\", err), \"GetObject\")\n    }\n
    4. To release resources after use, utilize the Close method of the bundle.

       defer bundle.Close()\n

    Full example here

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/","title":"Simple Tool for File Management (JS) - BNB Greenfield File Management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#building-file-management-tool-with-greenfield-sdk-js","title":"Building File Management Tool with Greenfield SDK (JS)","text":"

    Several Chain API libraries are available. These libraries manage the low-level logic of connecting to the Greenfield node, making requests, and handing the responses.

    In this tutorial, we\u2019ll use the JS-SDK library to interact with testnet.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#prerequisites","title":"Prerequisites","text":"

    Before getting started, you should be familiar with:

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#setup","title":"Setup","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#create-project","title":"Create Project","text":"BrowserNodejs

    Follow Quick Start to create the project.

    Create a new index.js:

    ```bash title=\"Nodejs create project\"\n> mkdir gnfd-app\n> cd gnfd-app\n> touch index.js\n```\n\nInstall SDK:\n\n```bash title=\"npm install deps\"\n> npm init -y\n> npm add @bnb-chain/greenfield-js-sdk\n```\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#create-greenfield-client","title":"Create Greenfield Client","text":"BrowserNodejs Create testnet Client
    import { Client } from '@bnb-chain/greenfield-js-sdk';\n\nconst client = Client.create('https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org, '5600');\n
    Create testnet client
    const {Client}  = require('@bnb-chain/greenfield-js-sdk');\n\n// testnet\nconst client = Client.create('https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org', '5600');\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#test-a-simple-function","title":"Test a simple function","text":"BrowserNodejs
    <button\nclassName=\"button is-primary\"\nonClick={async () => {\n    const latestBlockHeight = await client.basic.getLatestBlockHeight();\n\n    alert(JSON.stringify(latestBlockHeight));\n}}\n>\ngetLatestBlockHeight\n</button>\n
    index.js
    ;(async () => {\nconst latestBlockHeight = await client.basic.getLatestBlockHeight()\n\nconsole.log('latestBlockHeight', latestBlockHeight)\n})()\n

    Run index.js to get the latest block height:

    > node index.js\n

    This will output like:

    latestBlockHeight 3494585\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#get-address-balance","title":"Get Address balance","text":"

    In the previous step, we verified that the client was OK.

    Now we try more features for an account.

    BrowserNodejs
    <button\nclassName=\"button is-primary\"\nonClick={async () => {\n    if (!address) return;\n\n    const balance = await client.account.getAccountBalance({\n    address: address,\n    denom: 'BNB',\n    });\n\n    alert(JSON.stringify(balance));\n}}\n>\ngetAccountBalance\n</button>\n

    You can query an account\u2019s balance by calling account.getAccountBalance function.

    get account's balance
    ;(async () => {\n    const balance = await client.account.getAccountBalance({\n    address: '0x1C893441AB6c1A75E01887087ea508bE8e07AAae',\n    denom: 'BNB'\n})\n\nconsole.log('balance: ', balance)\n})()\n

    Run node index.js to get the account\u2019s balance:

    balance: { balance: { denom: 'BNB', amount: '4804586044359520195' } }\n

    Apart from the basic data queries shown above, there are many more features. Please see the API Reference for all Greenfield API definitions.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#manage-wallet","title":"Manage Wallet","text":"

    The wallet in Nodejs is generated by a private key, but the wallet plugin(MetaMask, CollectWallet, etc) can\u2019t get the user\u2019s private key in the browser, so another way is needed.

    BrowserNodejs
    <button\nclassName=\"button is-primary\"\nonClick={async () => {\n    if (!address) return;\n\n    const transferTx = await client.account.transfer({\n    fromAddress: address,\n    toAddress: '0x0000000000000000000000000000000000000000',\n    amount: [\n        {\n        denom: 'BNB',\n        amount: '1000000000',\n        },\n    ],\n    });\n\n    const simulateInfo = await transferTx.simulate({\n    denom: 'BNB',\n    });\n\n    const res = await transferTx.broadcast({\n    denom: 'BNB',\n    gasLimit: Number(simulateInfo.gasLimit),\n    gasPrice: simulateInfo.gasPrice,\n    payer: address,\n    granter: '',\n    signTypedDataCallback: async (addr: string, message: string) => {\n        const provider = await connector?.getProvider();\n        return await provider?.request({\n        method: 'eth_signTypedData_v4',\n        params: [addr, message],\n        });\n    },\n    });\n\n    if (res.code === 0) {\n    alert('transfer success!!');\n    }\n}}\n>\ntransfer\n</button>\n

    In general, we need to put the private key in the .env file and ignore this file in the .gitignore file (for account security).

    > touch .env\n

    Add this information to .env:

    # fill your account info\nACCOUNT_PRIVATEKEY=0x...\nACCOUNT_ADDRESS=0x...\n

    Install dotenv dependencies(for loading variables from .env):

    > npm install dotenv\n

    Everything is ready and we can transfer the transaction now.

    Create transfer.js file:

    transfer.js
    require('dotenv').config();\nconst {Client} = require('@bnb-chain/greenfield-js-sdk');\nconst client = Client.create('https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org', '5600');\n\n;(async () => {\n\n// construct tx\nconst transferTx = await client.account.transfer({\n    fromAddress: process.env.ACCOUNT_ADDRESS,\n    toAddress: '0x0000000000000000000000000000000000000000',\n    amount: [\n    {\n        denom: 'BNB',\n        amount: '1000000000',\n    },\n    ],\n})\n\n// simulate transfer tx\nconst simulateInfo = await transferTx.simulate({\n    denom: 'BNB',\n});\n\n// broadcast transfer tx\nconst res = await transferTx.broadcast({\n    denom: 'BNB',\n    gasLimit: Number(simulateInfo.gasLimit),\n    gasPrice: simulateInfo.gasPrice,\n    payer: process.env.ACCOUNT_ADDRESS,\n    granter: '',\n    privateKey: process.env.ACCOUNT_PRIVATEKEY,\n})\n\nconsole.log('res', res)\n})()\n

    Running node transfer.js:

    transfer tx response

    {\ncode: 0,\nheight: 3495211,\ntxIndex: 0,\nevents: [\n    { type: 'coin_spent', attributes: [Array] },\n    { type: 'coin_received', attributes: [Array] },\n    { type: 'transfer', attributes: [Array] },\n    { type: 'message', attributes: [Array] },\n    { type: 'tx', attributes: [Array] },\n    { type: 'tx', attributes: [Array] },\n    { type: 'tx', attributes: [Array] },\n    { type: 'message', attributes: [Array] },\n    { type: 'coin_spent', attributes: [Array] },\n    { type: 'coin_received', attributes: [Array] },\n    { type: 'transfer', attributes: [Array] },\n    { type: 'message', attributes: [Array] }\n],\nrawLog: '[{\"msg_index\":0,\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"/cosmos.bank.v1beta1.MsgSend\"},{\"key\":\"sender\",\"value\":\"0x1C893441AB6c1A75E01887087ea508bE8e07AAae\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"coin_spent\",\"attributes\":[{\"key\":\"spender\",\"value\":\"0x1C893441AB6c1A75E01887087ea508bE8e07AAae\"},{\"key\":\"amount\",\"value\":\"1000000000BNB\"}]},{\"type\":\"coin_received\",\"attributes\":[{\"key\":\"receiver\",\"value\":\"0x0000000000000000000000000000000000000000\"},{\"key\":\"amount\",\"value\":\"1000000000BNB\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"0x0000000000000000000000000000000000000000\"},{\"key\":\"sender\",\"value\":\"0x1C893441AB6c1A75E01887087ea508bE8e07AAae\"},{\"key\":\"amount\",\"value\":\"1000000000BNB\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"0x1C893441AB6c1A75E01887087ea508bE8e07AAae\"}]}]}]',\ntransactionHash: '1B731E99A55868F773E9A7C951D9325BE7995616B990924D47491320599789DE',\nmsgResponses: [\n    {\n    typeUrl: '/cosmos.bank.v1beta1.MsgSendResponse',\n    value: Uint8Array(0) []\n    }\n],\ngasUsed: 1200n,\ngasWanted: 1200n\n}\n

    More TxClient References.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#make-a-storage-deal","title":"Make a storage deal","text":"

    Storing data is one of the most important features of Greenfield. In this section, we\u2019ll walk through the end-to-end process of storing your data on the Greenfield network. We\u2019ll start by importing your data, then make a storage deal with a storage provider, and finally wait for the deal to complete.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#0-create-the-main-file","title":"0. Create the main file","text":"BrowserNodejs

    The browser doesn\u2019t need the main file.

    > touch storage.js\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#1-choose-your-own-sp","title":"1. Choose your own SP","text":"

    You can query the list of SP:

    BrowserNodejs utils/offchainAuth.ts
    export const getSps = async () => {\nconst sps = await client.sp.getStorageProviders();\nconst finalSps = (sps ?? []).filter((v: any) => v.endpoint.includes('nodereal'));\n\nreturn finalSps;\n};\n\nexport const getAllSps = async () => {\nconst sps = await getSps();\n\nreturn sps.map((sp) => {\n    return {\n    address: sp.operatorAddress,\n    endpoint: sp.endpoint,\n    name: sp.description?.moniker,\n    };\n});\n};\n\nexport const selectSp = async () => {\nconst finalSps = await getSps();\n\nconst selectIndex = Math.floor(Math.random() * finalSps.length);\n\nconst secondarySpAddresses = [\n    ...finalSps.slice(0, selectIndex),\n    ...finalSps.slice(selectIndex + 1),\n].map((item) => item.operatorAddress);\nconst selectSpInfo = {\n    id: finalSps[selectIndex].id,\n    endpoint: finalSps[selectIndex].endpoint,\n    primarySpAddress: finalSps[selectIndex]?.operatorAddress,\n    sealAddress: finalSps[selectIndex].sealAddress,\n    secondarySpAddresses,\n};\n\nreturn selectSpInfo;\n};\n\nconst getOffchainAuthKeys = async (address: string, provider: any) => {\nconst storageResStr = localStorage.getItem(address);\n\nif (storageResStr) {\n    const storageRes = JSON.parse(storageResStr) as IReturnOffChainAuthKeyPairAndUpload;\n    if (storageRes.expirationTime < Date.now()) {\n    alert('Your auth key has expired, please generate a new one');\n    localStorage.removeItem(address);\n    return;\n    }\n\n    return storageRes;\n}\n\nconst allSps = await getAllSps();\nconst offchainAuthRes = await client.offchainauth.genOffChainAuthKeyPairAndUpload(\n    {\n    sps: allSps,\n    chainId: GREEN_CHAIN_ID,\n    expirationMs: 5 * 24 * 60 * 60 * 1000,\n    domain: window.location.origin,\n    address,\n    },\n    provider,\n);\n\nconst { code, body: offChainData } = offchainAuthRes;\nif (code !== 0 || !offChainData) {\n    throw offchainAuthRes;\n}\n\nlocalStorage.setItem(address, JSON.stringify(offChainData));\nreturn offChainData;\n};\n
    storage.js
    ;(async () => {\n// get storage providers list\nconst sps = await client.sp.getStorageProviders()\n\n// choose the first up to be the primary SP\nconst primarySP = sps[0].operatorAddress;\n})()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#2-create-your-bucket","title":"2. Create your bucket","text":"

    Bucket can be private or public. You can customize it with options.

    VisibilityType:

    create bucket
    import { Long, VisibilityType, RedundancyType, bytesFromBase64 } from '@bnb-chain/greenfield-js-sdk';\nconst createBucketTx = await client.bucket.createBucket(\n  {\n    bucketName: info.bucketName,\n    creator: address,\n    visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,\n    chargedReadQuota: Long.fromString('0'),\n    primarySpAddress: spInfo.primarySpAddress,\n    paymentAddress: address,\n  },\n);\n\nconst simulateInfo = await createBucketTx.simulate({\n  denom: 'BNB',\n});\n\nconsole.log('simulateInfo', simulateInfo);\n\nconst res = await createBucketTx.broadcast({\n  denom: 'BNB',\n  gasLimit: Number(simulateInfo?.gasLimit),\n  gasPrice: simulateInfo?.gasPrice || '5000000000',\n  payer: address,\n  granter: '',\n});\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#3-create-object-and-upload-object","title":"3. Create Object and Upload Object","text":"

    Objects can also be private or public.

    Getting the file\u2019s checksum needs reed-solomon:

    BrowserNodejs
    import { ReedSolomon } from '@bnb-chain/reed-solomon';\n\nconst rs = new ReedSolomon();\n\n// file is File type\nconst fileBytes = await file.arrayBuffer();\nconst expectCheckSums = rs.encode(new Uint8Array(fileBytes));\n
    const fs = require('node:fs');\nconst { NodeAdapterReedSolomon } = require('@bnb-chain/reed-solomon/node.adapter');\n\nconst filePath = './CHANGELOG.md';\nconst fileBuffer = fs.readFileSync(filePath);\nconst rs = new NodeAdapterReedSolomon();\nconst expectCheckSums = await rs.encodeInWorker(__filename, Uint8Array.from(fileBuffer));\n

    Getting approval of creating an object and sending createObject txn to the Greenfield network:

    const createObjectTx = await client.object.createObject(\n  {\n    bucketName: info.bucketName,\n    objectName: info.objectName,\n    creator: address,\n    visibility: VisibilityType.VISIBILITY_TYPE_PRIVATE,\n    contentType: fileType,\n    redundancyType: RedundancyType.REDUNDANCY_EC_TYPE,\n    payloadSize: Long.fromInt(fileBuffer.length),\n    expectChecksums: expectCheckSums.map((x) => bytesFromBase64(x)),\n  },\n);\n\nconst simulateInfo = await createObjectTx.simulate({\n  denom: 'BNB',\n});\n\nconst res = await createObjectTx.broadcast({\n  denom: 'BNB',\n  gasLimit: Number(simulateInfo?.gasLimit),\n  gasPrice: simulateInfo?.gasPrice || '5000000000',\n  payer: address,\n  granter: '',\n});\n

    Upload Object:

    BrowserNodejs
    await client.object.uploadObject(\n{\n    bucketName: info.bucketName,\n    objectName: info.objectName,\n    body: info.file,\n    txnHash: txnHash,\n},\n{\n    type: 'EDDSA',\n    domain: window.location.origin,\n    seed: offChainData.seedString,\n    address,\n},\n);\n
    await client.object.uploadObject(\n{\n    bucketName: bucketName,\n    objectName: objectName,\n    body: createFile(filePath),\n    txnHash: createObjectTxRes.transactionHash,\n},\n{\n    type: 'ECDSA',\n    privateKey: ACCOUNT_PRIVATEKEY,\n}\n);\n\n// convert buffer to file\nfunction createFile(path) {\nconst stats = fs.statSync(path);\nconst fileSize = stats.size;\n\nreturn {\n    name: path,\n    type: '',\n    size: fileSize,\n    content: fs.readFileSync(path),\n}\n}\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#4-object-management","title":"4. Object management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#41-download-object","title":"4.1 Download object","text":"BrowserNodejs
    await client.object.downloadFile(\n{\n    bucketName: info.bucketName,\n    objectName: info.objectName,\n},\n{\n    type: 'EDDSA',\n    address,\n    domain: window.location.origin,\n    seed: offChainData.seedString,\n},\n);\n
    manage.js
    ;(async () => {\n\n// download object\nconst res = await client.object.getObject({\n    bucketName: 'extfkdcxxd',\n    objectName: 'yhulwcfxye'\n}, {\n    type: 'ECDSA',\n    privateKey: ACCOUNT_PRIVATEKEY,\n})\n\n// res.body is Blob\nconsole.log('res', res)\nconst buffer = Buffer.from([res.body]);\nfs.writeFileSync('your_output_file', buffer)\n})()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#42-update-object-visibility","title":"4.2 Update object visibility","text":"BrowserNodejs
    const tx = await client.object.updateObjectInfo({\nbucketName: info.bucketName,\nobjectName: info.objectName,\noperator: address,\nvisibility: 1,\n});\n\nconst simulateTx = await tx.simulate({\ndenom: 'BNB',\n});\n\nconst res = await tx.broadcast({\ndenom: 'BNB',\ngasLimit: Number(simulateTx?.gasLimit),\ngasPrice: simulateTx?.gasPrice || '5000000000',\npayer: address,\ngranter: '',\n});\n
    const tx = await client.object.updateObjectInfo({\nbucketName: 'extfkdcxxd',\nobjectName: 'yhulwcfxye',\noperator: ACCOUNT_ADDRESS,\nvisibility: 1,\n})\n\nconst simulateTx = await tx.simulate({\ndenom: 'BNB',\n})\n\nconst createObjectTxRes = await tx.broadcast({\ndenom: 'BNB',\ngasLimit: Number(simulateTx?.gasLimit),\ngasPrice: simulateTx?.gasPrice || '5000000000',\npayer: ACCOUNT_ADDRESS,\ngranter: '',\nprivateKey: ACCOUNT_PRIVATEKEY,\n});\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#43-delete-object","title":"4.3 Delete Object","text":"BrowserNodejs
    const tx = await client.object.deleteObject({\nbucketName: info.bucketName,\nobjectName: info.objectName,\noperator: address,\n});\n\nconst simulateTx = await tx.simulate({\ndenom: 'BNB',\n});\n\nconst res = await tx.broadcast({\ndenom: 'BNB',\ngasLimit: Number(simulateTx?.gasLimit),\ngasPrice: simulateTx?.gasPrice || '5000000000',\npayer: address,\ngranter: '',\n});\n
    ;(async () => {\nconst tx = await client.object.deleteObject({\n    bucketName: 'extfkdcxxd',\n    objectName: 'yhulwcfxye',\n    operator: ACCOUNT_ADDRESS,\n});\n\nconst simulateTx = await tx.simulate({\n    denom: 'BNB',\n})\n\nconst createObjectTxRes = await tx.broadcast({\n    denom: 'BNB',\n    gasLimit: Number(simulateTx?.gasLimit),\n    gasPrice: simulateTx?.gasPrice || '5000000000',\n    payer: ACCOUNT_ADDRESS,\n    granter: '',\n    privateKey: ACCOUNT_PRIVATEKEY,\n});\n\nif (createObjectTxRes.code === 0) {\n    console.log('delete object success')\n}\n})()\n
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#conclusion","title":"Conclusion","text":"

    Congratulations on making it through this tutorial! In this tutorial, we learned the basics of interacting with the Greenfield network using the SDK library.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/#tutorials-source-code","title":"Tutorials Source Code","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/","title":"Resumable Upload/Download Demo - BNB Greenfield File Management","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#resumable-upload-resumable-download","title":"Resumable Upload & Resumable Download","text":""},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#resumable-upload","title":"Resumable Upload","text":"

    Resumable upload refers to the process of uploading a file in multiple parts, where each chunk is uploaded separately.This allows the upload to be resumed from where it left off in case of interruptions or failures, rather than starting the entire upload process from the beginning.

    During resumable upload, if an error occurs during the PutObject operation, the subsequent upload attempts will first query the server-side for the progress of the previous upload. It will then resume the upload from the last offset.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#upload-process-overview","title":"Upload Process Overview","text":"
    1. Start the initial PutObject operation to upload the object.
    2. If an error occurs during the upload, such as a network interruption or server error, the upload process is interrupted.
    3. When resuming the upload, the next PutObject operation will initiate a query to the server to retrieve the progress of the previous upload.
    4. The server responds with the last offset from which the upload needs to resume.
    5. The PutObject operation resumes the upload from offset received from the server.
    6. The upload process continues from the point of interruption until completion.
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#putobject-options","title":"PutObject Options","text":"

    The PutObject operation in the Greenfield GO-SDK API allows you to upload an object to a bucket. It provides additional options for configuration through the PutObjectOptions struct. This document describes two new options introduced in the PutObjectOptions struct.

    indicate the resumable upload \u2018s part size, uploading a large file in multiple parts. The part size is an integer multiple of the segment size.

    indicate whether need to enable resumeable upload. Resumable upload refers to the process of uploading a file in multiple parts, where each part is uploaded separately.This allows the upload to be resumed from where it left off in case of interruptions or failures, rather than starting the entire upload process from the beginning.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#usage-example","title":"Usage Example","text":"
    var buffer bytes.Buffer\nerr := s.Client.PutObject(\n    ctx,\n    bucketName,\n    objectName,\n    int64(buffer.Len()),\n    bytes.NewReader(buffer.Bytes()),\n    types.PutObjectOptions{\n        PartSize:        1024 * 1024 * 16, // 16 MB\n        DisableResumable: false,\n    },\n)\n

    In the above example, we create a bytes.Buffer named buffer to hold the object data. We then use the PutObject operation to upload the object to the specified bucket and object name. The PutObjectOptions struct is passed with the desired options set. In this case, the PartSize is set to the default value of 16 MB, and the DisableResumable is set to false to enable resumable upload.

    Note: Make sure to replace the placeholder values (s.Client, s.ClientContext, bucketName, and objectName) with the actual variables or values relevant to your code.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#resumable-download","title":"Resumable Download","text":"

    The FGetObjectResumable function in the S3 Client API allows you to perform resumable downloads for large files. This function downloads a file from the specified bucket and object name to a local file, with the ability to resume the download in case of errors or interruptions.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#download-process-overview","title":"Download Process Overview","text":"
    1. Start the initial FGetObjectResumable function to download the file.
    2. During the download process, the function retrieves segments of the file from the server-side and appends them to an object_{operatoraddress}{getrange}.tmp file.
    3. If an error occurs during the download, such as a network interruption or server error, the download process is interrupted.
    4. When resuming the download, the subsequent FGetObjectResumable function first checks if the object_{operatoraddress}{getrange}.tmp file exists.
    5. If the object_{operatoraddress}{getrange}.tmp file exists, the function verifies the checksum to ensure the integrity of the partially downloaded file.
    6. If the object_{operatoraddress}{getrange}.tmp file does not exist or the checksum is invalid, the function starts a fresh download of the object from the server.
    7. The download process continues from the last offset, and appending the segments to the object_{operatoraddress}{getrange}.tmp file.
    8. Once the download is complete, the object_{operatoraddress}{getrange}.tmp file can be renamed or processed as needed.
    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#usage-example_1","title":"Usage Example","text":"
    err = s.Client.FGetObjectResumable(\n    s.ClientContext,\n    bucketName,\n    objectName,\n    newFile,\n    types.GetObjectOptions{},\n)\n

    In the above example, the FGetObjectResumable function is used to perform a resumable download of a file from the specified bucket and object name. If an error occurs during the download, the subsequent function calls will check the existence and validity of the object_{operatoraddress}{getrange}.tmp file, and resume the download from the last offset.

    "},{"location":"bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/#source-code","title":"Source code","text":""},{"location":"bnb-greenfield/for-validator/overview/","title":"Overview - BNB Greenfield","text":""},{"location":"bnb-greenfield/for-validator/overview/#overview","title":"Overview","text":""},{"location":"bnb-greenfield/for-validator/overview/#what-is-the-greenfield-blockchain","title":"What is the Greenfield Blockchain","text":"

    The Greenfield blockchain plays a pivotal role in the Greenfield ecosystem. It forms the core of the platform and is constructed on the Cosmos/Tendermint infrastructure. Within the Greenfield blockchain, there are two categories of states that exist on-chain:

    Transactions conducted on the Greenfield blockchain can alter the aforementioned states. These states and transactions make up the majority of the BNB Greenfield economic data.

    "},{"location":"bnb-greenfield/for-validator/overview/#how-greenfield-blockchain-works","title":"How Greenfield Blockchain Works","text":"

    The Greenfield Blockchain utilizes the Tendermint consensus mechanism, implementing a Proof-of-Stake approach to ensure network security. Validator election and governance are managed through a proposal-vote mechanism, following the governance module of Cosmos SDK. Greenfield\u2019s validators produce blocks every 2 seconds.

    As for the blockchain\u2019s native token, BNB serves as both gas and governance token. The initial BNB is locked on BNB Smart Chain (BSC) and subsequently re-minted on Greenfield. Cross-chain communication enables smooth flow of BNB and data operation primitives between Greenfield and BSC. The total circulation of BNB remains unaffected and will continue moving along the BNB Beacon Chain, BSC, and Greenfield.

    Tip

    Here is a good reading about the working principles of an application chain built on Tendermint.

    "},{"location":"bnb-greenfield/for-validator/overview/#validator-from-greenfield-blockchain","title":"Validator from Greenfield Blockchain","text":"

    The validators of the Greenfield Blockchain are integral to the network\u2019s security and reliability. However, their responsibilities extend well beyond that:

    1. Validators are tasked with achieving consensus on cross-chain events and relaying cross-chain packets to both Greenfield and BNB Smart Chain. This ensures that cross-chain transactions are executed quickly, securely, and with minimal cost.

    2. Validators play a key role in ensuring the integrity and availability of data provided by service providers (SPs). By challenging the data availability of SPs in a specific or random manner, validators can weed out malicious actors and those who provide subpar services. Punishing such actors through appropriate measures - such as slashing their stake, for example - helps to ensure the quality and reliability of services in the Greenfield ecosystem.

    3. Validators also have a say in the governance of the network. They vote on issues related to the future development of Greenfield\u2019s ecosystem and adjust various network parameters as necessary. This ensures that the network remains healthy and sustainable over time, while accommodating the changing needs and demands of its users.

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/","title":"Become Validator","text":""},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#become-validator","title":"Become Validator","text":""},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#minimum-requirements","title":"Minimum Requirements","text":""},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#setting-up-validator-node","title":"Setting up Validator Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#1-install-fullnode","title":"1. Install Fullnode","text":"

    Follow the instructions here to set up a full node.

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#2-prepare-validator-delegator-validator-bls-relayer-and-challenger-accounts","title":"2. Prepare validator, delegator, validator BLS, relayer, and challenger accounts","text":"

    Warning

    The current key generation and storage procedures are not very secure. It is highly recommended to implement a more robust method, particularly when dealing with keys like the delegator and operator keys.

    For enhanced security and best practices, the usage of the Cold Wallet and MPC Wallet is strongly encouraged.

    Note

    The keyring-backend supports multiple storage backends, some of which may not be available on all operating systems. See more details here.

    gnfd keys add validator --keyring-backend test\ngnfd keys add delegator --keyring-backend test\ngnfd keys add validator_bls --keyring-backend test --algo eth_bls\ngnfd keys add validator_relayer --keyring-backend test\ngnfd keys add validator_challenger --keyring-backend test\n

    Tip

    Alternatively, if you choose a different $KEY_HOME location and you are not using the suggested default ~/.gnfd, you may start the full node by using below script, where $KEY_HOME is your selected directory.

    gnfd keys add validator --keyring-backend test --home ${KEY_HOME}\ngnfd keys add delegator --keyring-backend test --home ${KEY_HOME}\ngnfd keys add validator_bls --keyring-backend test --algo eth_bls --home ${KEY_HOME}\ngnfd keys add validator_relayer --keyring-backend test --home ${KEY_HOME}\ngnfd keys add validator_challenger --keyring-backend test --home ${KEY_HOME}\n
    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#3-obtain-validator-delegator-validator-bls-relayer-and-challenger-account-addresses","title":"3. Obtain validator, delegator, validator BLS, relayer, and challenger account addresses","text":"

    Note

    Ensure you choose the correct \u2013keyring-backend and that \u2013home is set correctly if you saved the files in a custom folder in step 2.

    VALIDATOR_ADDR=$(gnfd keys show validator -a --keyring-backend test)\nDELEGATOR_ADDR=$(gnfd keys show delegator -a --keyring-backend test)\nRELAYER_ADDR=$(gnfd keys show validator_relayer -a --keyring-backend test)\nCHALLENGER_ADDR=$(gnfd keys show validator_challenger -a --keyring-backend test)\nVALIDATOR_BLS=$(gnfd keys show validator_bls --keyring-backend test --output json | jq -r '.pubkey_hex')\nVALIDATOR_BLS_PROOF=$(gnfd keys sign ${VALIDATOR_BLS} --keyring-backend test --from validator_bls)\nVALIDATOR_NODE_PUB_KEY=$(cat ${CONFIG_PATH}/config/priv_validator_key.json | jq -r '.pub_key.value')\n
    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#4-submit-a-create-validator-proposal","title":"4. Submit a Create Validator Proposal","text":"

    Replace the values in the following JSON and save it as create_validator_proposal.json:

    {\n \"messages\": [\n  {\n   \"@type\": \"/cosmos.staking.v1beta1.MsgCreateValidator\",\n   \"description\": {\n    \"moniker\": \"${NODE_NAME}\",\n    \"identity\": \"\",\n    \"website\": \"\",\n    \"security_contact\": \"\",\n    \"details\": \"\"\n   },\n   \"commission\": {\n    \"rate\": \"0.070000000000000000\",\n    \"max_rate\": \"1.000000000000000000\",\n    \"max_change_rate\": \"0.010000000000000000\"\n   },\n   \"min_self_delegation\": \"1000000000000000000000\",\n   \"delegator_address\": \"${DELEGATOR_ADDR}\",\n   \"validator_address\": \"${VALIDATOR_ADDR}\",\n   \"pubkey\": {\n    \"@type\": \"/cosmos.crypto.ed25519.PubKey\",\n    \"key\": \"${VALIDATOR_NODE_PUB_KEY}\"\n   },\n   \"value\": {\n    \"denom\": \"BNB\",\n    \"amount\": \"1000000000000000000000\"\n   },\n   \"from\": \"0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2\",\n   \"relayer_address\": \"${RELAYER_ADDR}\",\n   \"challenger_address\": \"${CHALLENGER_ADDR}\",\n   \"bls_key\": \"${VALIDATOR_BLS}\", \n   \"bls_proof\": \"${VALIDATOR_BLS_PROOF}\"\n  }\n ],\n \"metadata\": \"\",\n \"title\": \"Create ${NODE_NAME} Validator\",\n \"summary\": \"create ${NODE_NAME} validator\",\n \"deposit\": \"1000000000000000000BNB\"\n}\n
    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#41-run-create-validator-command-to-submit-the-proposal-by-local-keys-ensure-the-delegator-account-has-enough-bnb-tokens","title":"4.1 Run create validator command to submit the proposal by local keys. Ensure the delegator account has enough BNB tokens.","text":"

    Info

    If you are utilizing the Cold Wallet or MPC wallet, please proceed to step #4.2.

    gnfd tx staking create-validator ./create_validator_proposal.json --keyring-backend test --chain-id \"greenfield_1017-1\" --from ${DELEGATOR_ADDR} --node \"https://greenfield-chain.bnbchain.org:443\" -b sync --gas \"200000000\" --fees \"1000000000000000000BNB\" --yes\n

    gnfd tx staking create-validator ./create_validator_proposal.json --keyring-backend test --chain-id \"greenfield_5600-1\" --from ${DELEGATOR_ADDR} --node \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\" -b sync --gas \"200000000\" --fees \"1000000000000000000BNB\" --yes\n

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#42-submit-the-proposal-by-gnfd-tx-sender-ensure-the-delegator-account-has-enough-bnb-tokens","title":"4.2 Submit the proposal by gnfd-tx-sender. Ensure the delegator account has enough BNB tokens.","text":"

    Run command to generate the transaction details.

    gnfd tx staking create-validator ./create_validator_proposal.json --from ${DELEGATOR_ADDR} --print-eip712-msg-type\n

    Submit the transaction using gnfd-tx-sender.

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#5-wait-for-the-voting-until-the-proposal-is-passed","title":"5. Wait for the voting until the Proposal is passed.","text":"

    After submitting the proposal successfully, you must wait for the voting to be completed and the proposal to be approved. It will last 7days on mainnet while 1 day on testnet. Once it has passed and is executed successfully, you can verify that the node has become a validator.

    Warning

    Please ensure that the validator node is running before it is selected. And the validator is responsible for running relayer and runing challenger, please ensure all these services are running as expected.

    "},{"location":"bnb-greenfield/for-validator/run-node/become-validator/#6-query-all-validators","title":"6. Query all validators","text":"MainnetTestnet
    gnfd query staking validators --node \"https://greenfield-chain.bnbchain.org:443\"\n
    gnfd query staking validators --node \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/","title":"Run Challenger - BNB Greenfield Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#prerequisites","title":"Prerequisites","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#recommended-hardware","title":"Recommended Hardware","text":"

    The following lists the recommended hardware requirements: - Hardware Requirements: Desktop or laptop hardware running recent versions of Mac OS X, or Linux. - CPU: 4 cores - RAM: 4 GB - Relational database: Mysql

    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#key-preparation","title":"Key Preparation","text":"

    These two keys refer to validator_challenger and validator_bls created in become-validator step 2.

    You can retrieve them with the following commands.

    gnfd keys export validator_challenger --unarmored-hex --unsafe --keyring-backend test\n\ngnfd keys export validator_bls --unarmored-hex --unsafe --keyring-backend test\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#prepare-binary","title":"Prepare Binary","text":"

    Get the greenfield-challenger app by running the following command in your terminal:

    git clone --branch \"$(curl -s https://api.github.com/repos/bnb-chain/greenfield-challenger/releases/latest  | jq -r '.tag_name')\" https://github.com/bnb-chain/greenfield-challenger.git\ncd greenfield-challenger\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#config","title":"Config","text":"

    Modify config/config.json. Or, you can create a new one and specify the config path by --config-path flag when start the challenger.

    Info

    Reference for a complete config file

    1. Set your private key and bls key (via file or aws secret).

       \"greenfield_config\": {\n   \"key_type\": \"local_private_key\" or \"aws_private_key\" depending on whether you are storing the keys on aws or locally in this json file\n   \"aws_region\": set this if you chose \"aws_private_key\"\n   \"aws_secret_name\": set this if you chose \"aws_private_key\"\n   \"aws_bls_secret_name\": set this if you chose \"aws_private_key\"\n   \"private_key\": set this if you chose \"local_private_key\"\n   \"bls_private_key\": set this if you chose \"local_private_key\" \n    ...\n }\n

      Note

      The term private_key refers to the private key of the validator_challenger account, while bls_private_key refers to the private key of the validator_bls account. To obtain these private keys, you can follow the instructions provided in the key preparation section.

    2. Set your RPC Address and Chain ID

      MainnetTestnet
      \"greenfield_config\": {\n    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\n    chainId = \"greenfield_1017-1\"\n}\n
      \"greenfield_config\": {\n    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\n    chainId = \"greenfield_5600-1\"\n}\n
    3. Config your database settings.

      \"db_config\": {\n    \"dialect\": \"mysql\",\n    \"db_path\": \"your_db_path\"\n    \"key_type\": \"local_private_key\" or \"aws_private_key\" depending on whether you are storing the keys on aws or locally in this json file\n    \"aws_region\": set this if you chose \"aws_private_key\", else leave as \"\"\n    \"aws_secret_name\": set this if you chose \"aws_private_key\", else leave as \"\"\n    \"username\": set db username if you chose \"local_private_key\", else leave as \"\"\n    \"password\": set db password if you chose \"local_private_key\", else leave as \"\"\n    ...\n}\n
    4. Config your internal sp config (for metrics purpose).

      \"sp_config\": {\n    \"internal_sp_endpoints\": [] // list of internal sps' endpoints\n}\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#build","title":"Build","text":"

    Build binary:

    make build\n

    Build docker image:

    make build_docker\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#run","title":"Run","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#run-mysql-in-dockerthis-can-be-skipped-if-you-are-using-sqlite","title":"Run MySQL in Docker(this can be skipped if you are using sqlite)","text":"
    docker run --name gnfd-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#create-db-schema","title":"Create DB Schema","text":"

    Create schema in MySQL client:

    CREATE SCHEMA IF NOT EXISTS `challenger` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-challenger/#start-challenger","title":"Start Challenger","text":"
    ./build/greenfield-challenger --config-type [local or aws] --config-path config_file_path  --aws-region [aws region or omit] --aws-secret-key [aws secret key for config or omit]\n

    Example:

    ./build/greenfield-challenger --config-type local --config-path config/config.json\n

    Run docker:

    docker run -it -v /your/data/path:/greenfield-challenger -e CONFIG_TYPE=\"local\" -e CONFIG_FILE_PATH=/your/config/file/path/in/container -d greenfield-challenger\n

    Or you can deploy the greenfield challenger application using Helm Chart V3. Please refer to challenger-readme.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/","title":"Run Node - BNB Greenfield Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-node/#run-node","title":"Run Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-node/#minimum-system-requirements","title":"Minimum System Requirements","text":"

    The hardware must meet certain requirements to run a Full Node.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#setting-up-a-new-node","title":"Setting Up a New Node","text":"

    Info

    Please check the greenfield repo for information, including the correct version of the binaries to use and details about the config file

    1. You need to choose a home folder $NODE_HOME (i.e. ~/.gnfd) for Greenfield Chain. You can setup this by:

    mkdir ~/.gnfd\nmkdir ~/.gnfd/config\n
    2. Download app.toml, config.toml and genesis.json from https://github.com/bnb-chain/greenfield/releases and copy them into $NODE_HOME/config mainnettestnet
    wget  $(curl -s https://api.github.com/repos/bnb-chain/greenfield/releases/latest |grep browser_ |grep mainnet_config |cut -d\\\" -f4)\nunzip mainnet_config.zip\ncp mainnet_config/*  ~/.gnfd/config/\n
    wget  $(curl -s https://api.github.com/repos/bnb-chain/greenfield/releases/latest |grep browser_ |grep testnet_config |cut -d\\\" -f4)\nunzip testnet_config.zip\ncp testnet_config/*  ~/.gnfd/config/\n

    You can edit this moniker later, in the $NODE_HOME/config/config.toml file:

    # A custom human readable name for this node\nmoniker = \"<your_custom_moniker>\"\n

    Note

    Monikers can contain only ASCII characters. Using Unicode characters will render your node unreachable.

    Now your Full Node has been initialized.

    1. Start your Full Node.
    gnfd start\n

    Note

    Alternatively, if you choose a different $NODE_HOME location and you are not using the suggested default ~/.gnfd, you may start the full node by using below script, where $NODE_HOME is your selected directory.

    Example: If you set /usr/local/gnfd as your home directory. Run the Full Node with below command.

    gnfd start --home /usr/local/gnfd\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#additional-configuration","title":"Additional Configuration","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-node/#get-extra-information-from-your-fullnode","title":"Get Extra Information From Your Fullnode","text":"

    If you have a Full Node running, then you can publish extra messages to local files.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#monitor-syncing-process","title":"Monitor Syncing Process","text":"

    You can verify if state sync is done by curl localhost:26657/status several times and see whether latest_block_height is increasing in response.

    \"sync_info\": {\n  ...\n  \"latest_block_height\": \"280072\",\n  \"latest_block_time\": \"2023-04-07T01:58:13.572249854Z\",\n  ...\n}\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#prometheus-metrics","title":"Prometheus Metrics","text":"

    Prometheus is enabled on port 26660 by default, and the endpoint is /metrics.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-node/#tools","title":"Tools","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/","title":"Run Relayer - BNB Greenfield Node","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#run-relayer","title":"Run Relayer","text":"

    This tutorial is for running relayers for Greenfield to BSC and opBNB. Please note that they are using the same binary, but two individual processes which require different databases connected. Most configs for these two relayers are the same, with a few differences which will be illustrated below.

    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#prerequisites","title":"Prerequisites","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#recommended-hardware","title":"Recommended Hardware","text":"

    The following lists the recommended hardware requirements: - Hardware Requirements: Desktop or laptop hardware running recent versions of Mac OS X, or Linux. - CPU: 4 cores - RAM: 4 GB - Relational database: Mysql

    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#key-preparation","title":"Key Preparation","text":"

    These two keys refer to validator_relayer and validator_bls created in become-validator step 2.

    You can retrieve them with the following commands.

    gnfd keys export validator_relayer --unarmored-hex --unsafe --keyring-backend test\n\ngnfd keys export validator_bls --unarmored-hex --unsafe --keyring-backend test\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#prepare-binary","title":"Prepare binary","text":"

    Get the greenfield-relayer app by running the following command in your terminal:

    git clone --branch \"$(curl -s https://api.github.com/repos/bnb-chain/greenfield-relayer/releases/latest  | jq -r '.tag_name')\" https://github.com/bnb-chain/greenfield-relayer.git\ncd greenfield-relayer\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#config","title":"Config","text":"

    Modify config/config.json. Or, you can create a new one and specify the config path by --config-path flag when start the relayer.

    Info

    For Testnet config, refer to Testnet configure. You can use it as a template for your Mainnet config by adapting a few changes as illustrated below.

    1. Set relayer private key and bls private key import method (via file or aws secret) and keys, the block monitoring start heights.

      \"greenfield_config\": {\n  \"key_type\": \"local_private_key\", // or \"aws_private_key\" if you are using aws secret manager.\n   ...\n  \"aws_bls_secret_name\": \"\",\n  \"private_key\": \"your_private_key\", // this is the relayer private key for relaying transaction.\n  \"bls_private_key\": \"your_private_key\", // this is the bls key for signing crosschain package.\n  \"rpc_addrs\": [\n    \"https://greenfield-chain.bnbchain.org:443\"\n   ]\n  \"chain_id\": 1017,\n   ...\n  \"start_height\": 1,  // please change to the current block height of Greenfield network.\n  \"chain_id_string\": \"greenfield_1017-1\"\n}, \n\"bsc_config\": {\n  \"key_type\": \"local_private_key\",  // or \"aws_private_key\" if you are using aws secret manager.\n  ...\n  \"rpc_addrs\": [\n     \"BSC_RPC\"\n  ],\n  \"private_key\": \"your_private_key\", // same as the above one in greenfield_congfig.\n  \"gas_limit\": 20000000,\n  ...\n  \"start_height\": 0,   // please change to the current block height of BSC network.\n  \"chain_id\": 56  // 56 is BSC Mainnet chain id.\n}\n
      For setting up the relayer that crosschain to opBNB, modify the bsc_config as below.
      \"bsc_config\": {\n     \"op_bnb\": true, // this specifies that conifg is for opBNB crosschain.\n     \"key_type\": \"local_private_key\",  // or \"aws_private_key\" if you are using aws secret manager.\n     ...\n     \"rpc_addrs\": [\n        \"opBNB_RPC\"\n     ],\n     \"private_key\": \"your_private_key\", // same as the above one in greenfield_congfig.\n     \"gas_limit\": 20000000,\n     ...\n     \"start_height\": 0,   // please change to the current block height of opBNB network.\n     \"chain_id\": 204 // opBNB mainnet chain id\n   }\n
      Note: Refer to Greenfield Endpoints for Greenfield RPC address, BSC Endpoints for BSC RPC address, and use the appropriate ones based on your location, opBNB Endpoints for opBNB RPC address, and use the appropriate ones based on your location. You might encounter Rate limit issue for using official BSC/opBNB endpoints, we would highly recommend using 3rd Party RPCs, like the NodeReal MegaNode
    2. Config crossChain, greenfield light client and relayer hub smart contracts addresses, others can keep the default value, refer to this contract-list to get addresses for Mainnet/Testnet.

      BSC-MainnetBSC-TestnetopBNB-MainnetopBNB-Testnet
      \"relay_config\": {\n    ... \n    \"cross_chain_contract_addr\": \"0x77e719b714be09F70D484AB81F70D02B0E182f7d\",\n    \"greenfield_light_client_contract_addr\": \"0x433bB48Bd86c089375e53b2E2873A9C4bC0e986B\",\n    \"relayer_hub_contract_addr\": \"0x31C477F05CE58bB81A9FB4b8c00560f1cBe185d1\"\n}\n
      \"relay_config\": {\n  ... \n  \"cross_chain_contract_addr\": \"0xa5B2c9194131A4E0BFaCbF9E5D6722c873159cb7\",\n  \"greenfield_light_client_contract_addr\": \"0xa9249cefF9cBc9BAC0D9167b79123b6C7413F50a\",\n  \"relayer_hub_contract_addr\": \"0x91cA83d95c8454277d1C297F78082B589e6E4Ea3\"\n}\n
      \"relay_config\": {\n  ... \n  \"cross_chain_contract_addr\": \"0x7E376AEFAF05E20e3eB5Ee5c08fE1B9832b175cE\",\n  \"greenfield_light_client_contract_addr\": \"0xf51ba131716776685A805E8E4Ecc95be2f923B93\",\n  \"relayer_hub_contract_addr\": \"0xEd873b460C53D22f0FF3fc511854d9b8b16C4aE2\"\n}\n
      \"relay_config\": {\n  ... \n  \"cross_chain_contract_addr\": \"0xF0Bcf6E4F72bCB33b944275dd5c9d4540a259eB9\",\n  \"greenfield_light_client_contract_addr\": \"0xc50791892F6528E42A58DD07869726079C71F3f2\",\n  \"relayer_hub_contract_addr\": \"0x59ACcF658CC4589C3C41720fd48e869B97A748a1\"\n}\n
    3. Config the database settings.

          \"db_config\": {\n    \"dialect\": \"mysql\",\n    \"key_type\": \"local_private_key\",\n    \"aws_region\": \"\",\n    \"aws_secret_name\": \"\",\n    \"password\": \"${pass}\",\n    \"username\": \"${user}\",\n    \"url\": \"tcp(${host})/greenfield-relayer?charset=utf8&parseTime=True&loc=Local\",\n    \"max_idle_conns\": 10,\n    \"max_open_conns\": 100\n    }\n
      Note: Please replace ${pass}, ${user}, ${host} with your Mysql instance credential and host. And use a distinct database other than greenfield-relayer, e.g. greenfield-op-relayer when running the Greenfield Relayer for crosschain to opBNB on the same DB instance.
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#build","title":"Build","text":"

    Build the binary:

    make build\n

    Or Build docker image:

    make build_docker\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#run","title":"Run","text":""},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#create-db-schema","title":"Create DB Schema","text":"

    Make sure the database instance is running.

    Create schema by MySQL client:

    CREATE SCHEMA IF NOT EXISTS `greenfield-relayer` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;\n
    "},{"location":"bnb-greenfield/for-validator/run-node/run-relayer/#start-relayer","title":"Start Relayer","text":"
    ./build/greenfield-relayer --config-type [local or aws] --config-path config_file_path  --aws-region [aws region or omit] --aws-secret-key [aws secret key for config or omit]\n

    Example:

    ./build/greenfield-relayer --config-type local --config-path config/config.json\n

    Run docker:

    docker run -it -v /your/data/path:/greenfield-relayer -e CONFIG_TYPE=\"local\" -e CONFIG_FILE_PATH=/your/config/file/path/in/container -d greenfield-relayer\n

    Or you can deploy the greenfield relayer application using Helm Chart V3. Please refer to relayer-readme.

    "},{"location":"bnb-greenfield/getting-started/dcellar/","title":"Dcellar - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/dcellar/#use-greenfield-in-dcellar","title":"Use Greenfield in Dcellar","text":"

    DCellar is a powerful tool that allows users to initiate their decentralized data management journey on the Greenfield platform. It is developed based on Greenfield by Nodereal. With DCellar, users can store and share their data, as well as manage their account assets.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#login","title":"Login","text":"

    Simply open the web browser and navigate to dcellar.io. You will be greeted with a Welcome Screen that provides a simple and user-friendly interface.

    To get started, click on the Get Started button, and your wallet extension will automatically be activated. This will log you in with your current wallet account, allowing you to access all the features and functions of DCellar. With this easy and straightforward process, even first-time users can quickly get started with decentralized data management on the Greenfield platform.

    For first time users, you will need to add Greenfield Network to your Wallet, and you will be asked to switch your network to Greenfield Network to start following operations.

    You can also add Greenfield Network to your wallet manually, you can find it at bnbchainlist

    For returning users, you will stay logged in for a default time period. During the default time period, you will stay logged in when you come back. After that, you will need to login with wallet again. If you want to switch to your other wallet accounts, you can try Disconnect first, and then login again with another account.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#transfer-in","title":"Transfer In","text":"

    Before you can begin storing your objects with DCellar, you\u2019ll need to transfer several amounts of BNB tokens from your BSC account to your Greenfield account. These two accounts share the same account address, making the transfer process straightforward and hassle-free.

    By transferring BNB tokens to your Greenfield account, you\u2019ll be able to cover the transaction fees associated with storing and managing your objects on the Greenfield platform. Once you\u2019ve completed this step, you\u2019ll be ready to start using DCellar and taking advantage of all its powerful features and benefits.

    Once you\u2019ve logged in to DCellar, you can access the Transfer In tab by navigating to the Wallet Page. Before you begin the transfer process, it\u2019s important to ensure that you\u2019re currently using the BSC .

    If you\u2019re using the Greenfield Network, the Transfer In page will be displayed differently. To avoid any confusion, make sure that you\u2019re on the correct network before proceeding with the transfer process. By following these simple steps, you can quickly and easily transfer BNB tokens to your Greenfield account and start using DCellar to manage your decentralized data.

    Click Switch to BNB Smart Chain, your wallet will be notified, informing you to switch network, by clicking Switch Network button on wallet pop-up, you will be able to switch to BSC . If you haven\u2019t added a BSC network yet, wallet will ask you to add a network first, then switch to this network.

    You will be able to Transfer a certain amount of BNB token from your BSC account to your Greenfield account which shares the same address. Transfer In will cost you two kinds of fees, all charged by BNB token:

    Input the amount you want to Transfer In, Click Transfer In, your transaction will be sent. You can view your transaction details in explorer.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#create-bucket","title":"Create Bucket","text":"

    Before you start using DCellar to manage your objects, you should make sure you are currently under Greenfield Network. If you are under another network, you will be asked to Switch to BNB Greenfield first.

    A bucket is a logical container for storing objects in Greenfield. Once a bucket has been created, you can upload your objects to a certain bucket. After Login, you can see the New Bucket button at your bucket list page.

    After clicking New Bucket, a pop-up will show and you will be asked to enter a bucket name. Each bucket has a unique name that is assigned by the user when the bucket is created. Please follow the naming rules, carefully select your bucket name:

    By selecting a primary storage provider, you will decide the main storage service provider for all the datas within this particular bucket.

    By selecting a payment account, all storage service fee will be charged from this selected payment account, while gas fee will charged from your current login account, which is also your owner account. If your balance is insufficient, you will be informed to Transfer In first. For more information about Owner Account and Payment Account, Please Go to Greenfield Doc- Greenfield Documentation.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#upload-object","title":"Upload Object","text":"

    Choose one bucket on your bucket list page, you can see the objects within this bucket. Click Upload , you will be able to choose a locally stored object.

    When you are uploading a object, gas fee will be charged from your current login account, which is also your owner account. Besides, once your object is uploaded successfully, you will be charging a storage fee under a certain flow rate. Therefore, when you are uploading a object, you need to make sure that your owner account has enough balance to cover the storage fee for the following six months. which will be shown as Prepaid fee as follows.

    Info

    Please notice that the prelocked fee is not charged at the beginning, it is still in your owner account. But you are not allowed to use it for other purposes because it\u2019s \u201clocked\u201d.

    Besides prepaid fee, each operation will bring settlement, which might generate settlement fee. Learn more about Greenfield Settlement.

    Moreover, you can select the permission property of the selected object, DCellar will set your object as private by default.

    After you successfully upload your data, Greenfield will start to charge storage fee from your locked fee in your account. You can view your total \u201clocked fee\u201d at your account page.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#create-folder","title":"Create Folder","text":"

    You can create folders to better organize your objects. carefully choose your folder name, avoid \u201c/\u201d in your folder name.

    Create folder will cost you some gas fee. Also, every operation will bring settlement, so there might be settlement fee. Settlement fee will be charged from the payment account, while gas fee will be charged from owner account.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#download-object","title":"Download Object","text":"

    When you are downloading a object, gas fee will not be charged. But it will cost your some Download bandwidth.

    Info

    Each download operation will consume Download Quota, which is related to object size. In the current testing phase, each bucket will be given 1G\u2019s free quota.

    You can check your bucket\u2019s remaining quota at Bucket Detail page

    When your remaining quota is smaller than the required quota for a certain object you are downloading, your download will fail, you will be reminded to buy more quota.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#manage-quota","title":"Manage Quota","text":"

    You can buy quota by month. Choose the amount you want to buy. Please notice that when you download objects, the system will automatically use the free quota first, which will not expire during your usage period. After your free quota is used out, system will start to use the download quota you bought. If your purchased quota is not use out before the end of the month, your monthly quota will expire.

    When you buy monthly quota, it means you agree to buy monthly quota in the following month, if you want to stop buying monthly quota, you need to update your monthly quota, set monthly quota amount to 0.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#delete-object","title":"Delete Object","text":"

    When you are deleting a object, gas fee will be charged from your owner account. If your balance is insufficient, you will be informed to Transfer In first. Besides, when your object is deleted, your flow rate will be recalculated, and part of your prepaid fee will be refund. So you can see your \u201cPrepaid fee refund\u201d as follows when deleting a object.

    Info

    Please notice if your data has been stored less than 6 months, your prepaid fee will not be refund.

    Also, every operation will bring settlement, so there might be settlement fee. Settlement fee will be charged from the payment account.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#delete-bucket","title":"Delete Bucket","text":"

    You can delete the bucket created by you. Please notice you are only allowed to delete an empty bucket, which means you need to delete all your objects in the bucket before you delete the bucket. When you are deleting a bucket, gas fee will be charged from your current login account, which is also your owner account.

    If you have bought monthly quota for the bucket, when you delete bucket, system will refund your prepaid fee for monthly quota no matter when you decide to delete your bucket. This is a bit different with prepaid fee refund when deleting objects, which has 6 6-month min lock time.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#monitor-usage","title":"Monitor Usage","text":"

    With DCellar, you can Monitor your usage through your Dashboard.

    Besides, you can also view your expenses via account and account detail.

    "},{"location":"bnb-greenfield/getting-started/dcellar/#send","title":"Send","text":"

    With the DCellar, you can easily send BNB tokens from your Greenfield owner account to another Greenfield owner account. However, before you initiate any token transfers, it\u2019s important to ensure that you\u2019re currently using the correct network. If you\u2019re using the BSC instead of the Greenfield , the Send page will be displayed differently. To avoid any mistakes or confusion, always double-check that you\u2019re on the correct network before sending tokens to another user. By taking this simple precaution, you can ensure that your token transfers are executed smoothly and efficiently, enabling you to manage your decentralized data with ease using DCellar.

    To switch to the BNB Greenfield network, simply click on the \u201cSwitch to BNB Greenfield\u201d button within DCellar. This will automatically activate your wallet extension, which will display a pop-up informing you that you need to switch networks. To proceed, simply click on the \u201cSwitch Network\u201d button within the wallet pop-up. This will allow you to switch to the Greenfield .

    Info

    Before Sending, please make sure the address you enter is a valid Greenfield account address.

    Enter the receiver\u2019s address and the amount you want the send, click Send, your transaction will be sent to Greenfield , and you will need to pay the gas fee on Greenfield .

    "},{"location":"bnb-greenfield/getting-started/dcellar/#transfer-out","title":"Transfer Out","text":"

    With DCellar, you can transfer out BNB token from your Greenfield account to your BSC account which shares the same address. Before you Transfer Out, you should make sure you are currently under Greenfield . If you are under BSC , your Transfer Out page will be shown as follows:

    To switch to the BNB Greenfield network, simply click on the Switch to BNB Greenfield button within DCellar. This will automatically activate your wallet extension, which will display a pop-up informing you that you need to switch networks. To proceed, simply click on the Switch Network button within the wallet pop-up. This will allow you to switch to the Greenfield , where you can begin managing your decentralized data with DCellar. By following these simple steps, you can quickly and easily switch networks and access all the powerful features and functions of DCellar on the Greenfield platform.

    Transfer Out will cost you two kinds of fees, all charged by BNB token:

    Input the amount you want to Transfer Out, Click Transfer Out, your transaction will be sent. You can view your transaction details in GreenfieldScan.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/","title":"General FAQ - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/general-faqs/#why-cant-i-send-bnb-tokens-on-bnb-greenfield-using-my-wallet","title":"Why can\u2019t I send BNB tokens on BNB Greenfield using my wallet?","text":"

    Wallet does not support transfers on BNB Greenfield because BNB Greenfield uses a different transaction format than other EVM chains. You may encounter the following error when you transfer your token with your wallet. To send BNB tokens on BNB Greenfield, you need to use dCellar Transfer function.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#how-to-understand-the-amount-field-in-the-signature-message-when-using-bnb-greenfield","title":"How to understand the amount field in the signature message when using BNB Greenfield?","text":"

    When users perform actions on the BNB Greenfield, such as creating buckets or uploading files, they need to sign a message that contains the amount of BNB they are spending. However, this amount is not in BNB units, but in WEI units, which are much smaller. One WEI is equal to 10^-18 BNB. Therefore, the amount field in the signature message may look very large, but it is actually a very small fraction of a BNB.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#does-greenfield-have-a-token-how-can-i-get-it","title":"Does Greenfield have a token? How can I get it?","text":"

    BNB remains the main utility token on Greenfield, no other token on Greenfield. You can acquire BNB in multiple ways:

    1. Buy BNB if you never own it.
    2. Cross-chain transfer BNB from BSC network to Greenfield using DCellar if you already own any BNB. You can read the detailed steps here. The cross-chain token transfer is really fast, you are supposed to receive your BNB within a minute.
    3. Receive BNB from other Greenfield users with internal transactions
    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-the-utility-of-bnb-on-greenfield","title":"What is the utility of BNB on Greenfield?","text":"

    BNB is used as a staking token, gas token, storage service fee token, and governance token. Refer to token economics for more details.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#does-greenfield-support-smart-contract","title":"Does Greenfield support smart contract?","text":"

    The Greenfield blockchain does not support smart contracts, but the native cross-chain between BSC and Greenfield brings programmability to the ecosystem. More tech details are explained here, you can start integrating smart contracts with Greenfield following the tutorial.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-consensus-algorithm-does-greenfield-run-on","title":"What consensus algorithm does Greenfield run on?","text":"

    Tendermint is the consensus engine that powers Greenfield BPoS.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#is-the-file-permanently-stored-in-greenfield","title":"Is the file permanently stored in Greenfield?","text":"

    No. Currently, Greenfield charges storage fees in a stream manner, so if a user\u2019s account balance is insufficient and in arrears, it is possible that their data may be lost and cannot be recovered.

    Greenfield may support permanent storage in the future.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#can-i-update-the-files-after-it-is-uploaded","title":"Can I update the files after it is uploaded?","text":"

    The update is not yet supported, but it can be accomplished through deletion and upload.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#can-i-enjoy-lower-price-for-the-data-i-previously-stored-if-the-storage-price-goes-down","title":"Can I enjoy lower price for the data I previously stored if the storage price goes down?","text":"

    Sure, but it requires any transaction that modifies the payment flow, such as uploading or deleting files, to trigger it.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#will-i-also-have-to-pay-more-for-the-data-i-have-previously-stored-if-the-storage-price-goes-up","title":"Will I also have to pay more for the data I have previously stored if the storage price goes up?","text":"

    In theory, yes. However, Greenfield will strictly limit the frequency and magnitude of price adjustments by storage providers to minimize the impact on users.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#if-the-storage-provider-loses-my-data-or-refuses-to-provide-service-what-can-i-do","title":"If the storage provider loses my data or refuses to provide service, what can I do?","text":"

    This situation is usually unlikely to happen because Greenfield uses redundant error-correction coding to keep your data safe across multiple storage providers.

    If such a scenario occurs, you can initiate a data availability challenge, and validators will verify the integrity, availability, and service quality of your data while penalizing the corresponding storage provider.

    You can continue to receive rewards until the storage provider fully recovers your data or provides the service.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#how-can-i-make-my-valuable-data-circulate","title":"How can I make my valuable data circulate?","text":"

    You can mirror your data and access permissions to the BNB Smart Chain network, and trade your data through various DApps and data trading platforms.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#how-long-can-the-data-uploaded-to-the-testnet-be-saved","title":"How long can the data uploaded to the testnet be saved?","text":"

    Testnet is used for testing, so it won\u2019t keep user\u2019s data for a long time. It is expected to be dropped after 7 days.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-to-do-if-you-are-unable-to-upgrade-greenfield-in-time","title":"What to do if you are unable to upgrade Greenfield in time?","text":"

    Since this is a hardfork, your gnfd binary cannot continue running if it\u2019s not upgraded in time. Add the following filed in app.toml:

    # chain-id for op bnb destination chain \n`dest-op-chain-id = 204`\n
    Stop the binary, then execute the rollback command: gnfd rollback --hard Finally, restart your binary."},{"location":"bnb-greenfield/getting-started/general-faqs/#how-much-does-it-cost-to-store-files-in-greenfield","title":"How much does it cost to store files in Greenfield?","text":"

    If you\u2019re interested in knowing the real-time pricing for storage and querying on Greenfield, we invite you to the Price Calculator.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#how-is-my-billing-calculated","title":"How is my billing calculated?","text":"

    In Greenfield, bsides transaction fee, users are required to pay two kinds of storage service fees: storage fee and download quota fee. These storage service fees are charged by Storage Providers (SPs) in a stream payment. Users need to lock some BNB when they start using the service.

    Storage Fee = sum(ChargedSize) * (PrimaryStorePrice + SecondaryStorePrice*SecondarySPNumber) * (1+Validator Tax Rate) * ReserveTime\n
    Download Quota Fee = ChargedReadQuota * ReadPrice * (1 + Validator Tax Rate) * ReserveTime\n

    Currently, ReserveTime is 180 days and Validator Tax Rate is 1%

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-charged-size","title":"What is Charged Size?","text":"

    The ChargeSize is calculated from the object\u2019s payload size, if the payload size is less than 128k then ChargeSize is 128k, otherwise ChargeSize is equal to payload size.

    If Data Size < 128K, ChargedSize = 128K; else, ChargedSize = Data Size

    If object is an empty folder, ChargedSize = 128K

    You can query the value from this API

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-primarysecondary-store-price","title":"What is Primary/Secondary Store Price?","text":"

    Every SP can set their own suggested store price and read price via on-chain transactions. At the first block of each month, the median all SPs\u2019 store prices will be calculated as the Primary SP Store Price, the Secondary SP Store Price will be calculated as SecondaryPriceRatio (e.g. 12%, which can be governed) multiply the Primary SP Store Price , and the median of all SPs\u2019 read prices will be calculated as the Primary SP Read Price. To learn more about it, please refer to this

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-validator-tax-rate","title":"What is Validator Tax Rate?","text":"

    For each data related operation on Greenfield, validators can get some rewards for protecting the security and integrity of data (i.e. challenge). Through charging validator tax, part of user\u2019s cost will go to validator tax pool, and then become validators\u2019 rewards.

    You can query the value from this API

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-read-price","title":"What is Read Price?","text":"

    A storage provider can update its free read quote and monthly gree read quota, suggested primary store price and read price. All SPs\u2019 suggested primary store and read prices will be used to generate the global primary/secondary store price and read price.

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#what-is-reserve-time","title":"What is Reserve Time?","text":"

    The storage fee will be charged on Greenfield in a steam payment style. The fees are paid on Greenfield in the style of \u201cStream\u201d from users to receiver accounts at a constant rate. By reseveing some balance, users do not need to payment the fee in a very high frequency. Currently, the reserve time is 6 months and it can be governed.

    You can query the value from this API

    "},{"location":"bnb-greenfield/getting-started/general-faqs/#whats-best-practice-to-store-small-files-in-greenfield","title":"What\u2019s best practice to store small files in Greenfield?","text":"

    If a single transaction only store a small size file to the Greenfield Network, it is like separate packages being sent through the mail \u2013 even though they were all going to the same destination. It\u2019s recommended to take all of the files to reach the Charged Size and put them together to get sent as one transaction to the network.

    "},{"location":"bnb-greenfield/getting-started/get-test-bnb/","title":"Faucet - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/get-test-bnb/#faucet","title":"Faucet","text":"

    You can claim the test tBNB tokens on BSC Testnet by the faucet, and bridge it to Greenfield Testnet.

    "},{"location":"bnb-greenfield/getting-started/get-test-bnb/#claim-tbnb-from-bsc-faucet","title":"Claim tBNB from BSC Faucet","text":"
    1. Vist BSC faucet.

    2. Switch to the BSC Testnet in your wallet and check your balance.

    "},{"location":"bnb-greenfield/getting-started/get-test-bnb/#bridge-to-greenfield","title":"Bridge to Greenfield","text":"

    You can use BNB Greenfield Bridge or DCellar Testnet to transfer BNB from BSC to Greenfield and vice versa. You can follow How to Transfer In to bridge tBNBs from BSC Testnet to Greenfield Testnet, and How to Transfer Out to bridge tBNBs from Greenfield Testnet to BSC Testnet.

    "},{"location":"bnb-greenfield/getting-started/greenfield-command/","title":"Greenfield Command - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/greenfield-command/#greenfield-command","title":"Greenfield Command","text":"

    Greenfield Command is a powerful command line for you to manage your resources on Greenfield and interact with Greenfield.

    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#command-tool-guide","title":"Command Tool Guide","text":"

    This command tool supports basic storage functions, including creating buckets, uploading and downloading files, and deleting resources. It also supports related operations such as groups, policies, banks, accounts and so on. To make the command display clearer, commands of different categories are implemented as subcommands of different categories. You can use \u201cgnfd-cmd -h\u201d to view the supported command categories.

    The command tool supports the \u201c\u2013home\u201d option to specify the path of the config file and the keystore, the default path is a directory called \u201c.gnfd-cmd\u201d under the home directory of the system. When running commands that interact with the greenfield, if there is no config/config.toml file under the path and the commands runs without \u201c\u2013config\u201d flag, the tool will generate the config/config.toml file automatically which is consistent with the testnet configuration under the path.

    Below is examples of the config file of Testnet and Mainnet. The rpcAddr and chainId should be consistent with the Greenfield network. For Greenfield Mainnet, you can refer to Greenfield Mainnet RPC Endpoints. The rpcAddr indicates the Tendermint RPC address with the port info.

    The command has the ability to intelligently select the correct storage provider to respond to the request. The user only needs to set the storage provider operator-address if they want to create a bucket on a specific SP. For example, the user can run \u201cgnfd-cmd storage put test gnfd://bucket1/object1\u201d to upload a file to bucket1 and then run \u201cgnfd-cmd storage put test gnfd://bucket2/object\u201d to upload a file to bucket2, which is stored on another SP without changing the config.

    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#basic-operations","title":"Basic Operations","text":""},{"location":"bnb-greenfield/getting-started/greenfield-command/#account-operations","title":"Account Operations","text":"

    Before using the rich features of the command tool, you need to init account info and generate keystore by \u201caccount import\u201d or \u201caccount new\u201d command . All the other commands need to load the keystore content before running.

    The \u201cimport\u201d command imports account info from private key file and generate a keystore by following four steps:

    1. Export your private key from MetaMask and write it into a local file as plaintext (You can select \u201cAccount Details\u201d from the dropdown menu of MetaMask. Click on the \u201cExport Private Key\u201d button at the bottom of the page.)
    2. Generate a keystore by the \u201caccount import [keyfile]\u201d command. Users need set the private key file path, which is created by step 1.
      // import key and generate a keystore file \ngnfd-cmd account import key.txt\n
    3. The terminal will prompt user to enter the password information. Users can also specify the password file path by using the \u201c\u2013passwordfile\u201d. Users are responsible for managing their password information.

    The keystore will be generated in the path \u201ckeystore/keyfile\u201d under the home directory of the system or the directory set by \u201c-home\u201d. And it is also the path to load keystore when running other commands.

    1. Delete the private key file which is created in step 1. It is not needed after the keystore has been generated.

    If the user has no private key to import, he can use \u201caccount new\u201d create a new greenfield account and the keystore. After creating the account, the user needs to transfer token to the address of this account before using other commands to send transactions or use storage-related functions.

    // new account and generate keystore key.json\ngnfd-cmd account account new\n

    To obtain the account and keystore info, users can use \u201caccount export\u201d to print the private key info and \u201caccount ls\u201d to display the accounts information.

    // list the account info and keystore path\ngnfd-cmd account ls\n\n// display the encrypted keystore or the private key \ngnfd-cmd account export --unarmoredHex --unsafe\n

    Users can create multiple accounts using the \u201caccount import\u201d or \u201caccount new\u201d command. You can use the \u201cset-default\u201d command to specify which account to use for running other commands by default. When executing commands using the default account, there is no need to specify the keystore.

    // set the default account.\ngnfd-cmd account set-default [address]\n
    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#sp-operations","title":"SP Operations","text":"

    Before making a bucket and uploading files, we need to select a storage provider to store the files in the bucket. By executing the following command, we can obtain a list of storage providers on Greenfield.

    $ gnfd-cmd sp ls\nname     operator address                           endpoint                               status\nbnbchain 0x231099e40E1f98879C4126ef35D82FF006F24fF2 https://greenfield-sp.bnbchain.org:443 IN_SERVICE\ndefibit  0x05b1d420DcAd3aB51EDDE809D90E6e47B8dC9880 https://greenfield-sp.defibit.io:443   IN_SERVICE\nninicoin 0x2901FDdEF924f077Ec6811A4a6a1CB0F13858e8f https://greenfield-sp.ninicoin.io:443  IN_SERVICE\nnariox   0x88051F12AEaEC7d50058Fc20b275b388e15e2580 https://greenfield-sp.nariox.org:443   IN_SERVICE\nlumibot  0x3131865C8B61Bcb045ed756FBe50862fc23aB873 https://greenfield-sp.lumibot.org:443  IN_SERVICE\nvoltbot  0x6651ED78A4058d8A93CA4979b7AD516D1C9010ac https://greenfield-sp.voltbot.io:443   IN_SERVICE\nnodereal 0x03c0799AD70d19e723359E036a83E8f44f4B8Ba7 https://greenfield-sp.nodereal.io:443  IN_SERVICE\n
    And the Users can obtain detailed information about a certain SP by \u201csp head\u201d and \u201csp get-price\u201d commands. Here is an example of obtaining information about an SP with endpoint https://greenfield-sp.nodereal.io:443.
    // get storage provider info\n$ gnfd-cmd sp head  https://greenfield-sp.nodereal.io:443\n\n// get quota and storage price info of storage provider:\n$ gnfd-cmd sp get-price https://greenfield-sp.nodereal.io:443\nget bucket read quota price: 0.1469890427  wei/byte\nget bucket storage price: 0.02183945725  wei/byte\nget bucket free quota: 1073741824\n

    You can take note of the operator-address information for the storage provider to which is intended to be uploaded. This parameter will be required for making the bucket in the next step.

    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#bucket-operation","title":"Bucket Operation","text":"

    You can run \u201c./gnfd-cmd bucket -h \u201d to get help of the bucket operations.

    The below command can be used to create a new bucket called testbucket:

    gnfd-cmd bucket create gnfd://testbucket\n

    The command supports \u201c-primarySP\u201d flag to select the storage provider on which you want to create a bucket. The content of the flag should be the operator address of the storage provider. If this value is not set, the first SP in the storage provider list will be selected as the upload target by default.

    The user can update the bucket meta by the \u201cbucket update\u201d command. It supports updating bucket visibility, charged quota, or payment address.

    // update bucket charged quota \ngnfd-cmd bucket update --chargedQuota 50000 gnfd://testbucket\n// update bucket visibility\ngnfd-cmd bucket update --visibility=public-read gnfd://testbucket\n

    The user can use list the buckets which belong to him with \u201cbucket ls\u201d commands.

     gnfd-cmd bucket ls\n
    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#uploaddownload-files","title":"Upload/Download Files","text":"

    (1) put Object

    The user can upload the local file to the bucket by the \u201cobject put\u201d command. The following command example uploads an object named \u2018testobject\u2019 to the \u2018testbucket\u2019 bucket. The file payload for the upload is read from the local file indicated by \u2018file-path\u2019.

    gnfd-cmd object put --contentType \"text/xml\" file-path gnfd://testbucket/testobject\n

    If the object name has not been set, the command will use the file name as object name. After the command is executed, it will send createObject txn to the chain and uploads the payload of the object to the storage provider. The command will return after object completes sealing. Users can also choose to interrupt the sealing process, which does not affect the final completion of the object. During the upload process, the terminal will print the upload progress and upload speed.

    (2) download object

    The user can download the object into the local file by the \u201cobject get\u201d command. The following command example downloads \u2018testobject\u2019 from \u2018testbucket\u2019 to the local \u2018file-path\u2019 and prints the length of the downloaded file. The filepath can be a specific file path, a directory path, or not set at all. If the file-path is not set, the command will download the content to a file with the same name as the object name in the current directory.

    gnfd-cmd object get gnfd://testbucket/testobject file-path\n

    After the command is executed, it will send a download request to the storage provider and download the object. The terminal will print the download progress and speed.

    (3) list object and delete object

    The user can use list the objects of the specific bucket with \u201cobject ls\u201d command.

     gnfd-cmd object ls gnfd://testbucket\n
    The user can delete the object with \u201cobject delete\u201d command.
     gnfd-cmd object delete gnfd://testbucket/testobject \n
    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#group-operation","title":"Group Operation","text":"

    Users can run \u201c./gnfd-cmd group -h \u201d to get help of group operations.

    The user can create a new group by the \u201cgroup create\u201d command. Note that this command can set the initialized group member through the \u2013initMembers parameter. After the command executes successfully, the group ID and transaction hash information will be returned.

    You can add or remove members from a group using the \u201cgroup update\u201d command. The user can use \u2018\u2013addMembers\u2019 to specify the addresses of the members to be added or \u2018\u2013removeMembers\u2019 to specify the addresses of the members to be removed.

    // create group\ngnfd-cmd group create gnfd://testGroup\n// update member\ngnfd-cmd group update --groupOwner 0x.. --addMembers 0x.. gnfd://testGroup\n
    "},{"location":"bnb-greenfield/getting-started/greenfield-command/#policy-operation","title":"Policy Operation","text":"

    Users can run \u201c./gnfd-cmd policy -h \u201d to get help of permission operations.

    Users can use the \u201cpolicy put [RESOURCE-URL]\u201d command to assign resource permissions to other accounts or groups (called principal), such as the permission to delete objects. After the command executes successfully, the object policy information of the principal will be returned. The principal is set by \u2013groupId which indicates the group or \u2013grantee which indicates the account.

    The resource url can be the follow types:

    1) \u201cgrn:b::bucket-name\u201d, it indicates the bucket policy

    2) \u201cgrn:o::bucket-name/object-name\u201d, it indicates the object policy

    3) \u201cgrn:g:owner-address:group-name\u201d, it indicates the group policy

    // put object policy \ngnfd-cmd policy put --groupId 11 --actions get,delete grn:o::gnfd-bucket/gnfd-object\n\n// put bucket policy\ngnfd-cmd policy put --grantee 0x.. --actions delete  grn:b::gnfd-bucket\n

    Users can also revoke permission by \u201cpolicy delete\u201d command

    // delete the bucket policy from a group\ngnfd-cmd policy delete --groupId 11  grn:b::gnfd-bucket\n\n// delete the object policy from an grantee\ngnfd-cmd policy delete --grantee 0..  grn:o::gnfd-bucket/gnfd-object\n

    Users can list the policy of the grantee or group-id by \u201cpolicy ls\u201d command

    // list policy info of a group\ngnfd-cmd policy ls --groupId 11  grn:o::gnfd-bucket/gnfd-object\n

    In addition to the basic commands mentioned above, the Greenfield Command also supports functions such as transferring tokens and payment account operations. You can find more examples in the readme file of Greenfield Command.

    "},{"location":"bnb-greenfield/getting-started/token-transfer/","title":"BNB Transfer - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/token-transfer/#bridge-and-transfer-bnb","title":"Bridge and Transfer BNB","text":"

    The address formats of Greenfield and BSC are fully compatible. Users can transfer BNB between Greenfield and BSC freely. However, Greenfield only supports BNB and does not support BEP20 tokens currently.

    This is a comprehensive guide detailing the process of transferring BNB between Greenfield Blockchain and BSC.

    "},{"location":"bnb-greenfield/getting-started/token-transfer/#transfer-from-bsc-to-greenfield","title":"Transfer from BSC to Greenfield","text":"

    To perform a cross-chain transfer from BNB Smart Chain (BSC) to Greenfield, follow these steps:

    1. Visit Greenfield Bridge.

    2. Connect your wallet and switch to the BSC network.

    3. Specify the desired amount and click the Transfer In button.

    4. Confirm the transaction and wait for the transfer to be processed on BSC.

    5. Once the transaction is confirmed, the funds will be transferred from BSC to Greenfield. The transferred funds will reflect in the same account on Greenfield within a few seconds.

    You can also use DCellar and follow How to Transfer In to transfer BNBs from BSC to Greenfield.

    "},{"location":"bnb-greenfield/getting-started/token-transfer/#transfer-from-greenfield-to-bsc","title":"Transfer from Greenfield to BSC","text":"

    To perform a cross-chain transfer from Greenfield to BNB Smart Chain (BSC), you will need to:

    1. Visit Greenfield Bridge.

    2. Connect your wallet and switch to the Greenfield network.

    3. Specify the desired amount and click the Transfer Out button.

    4. Confirm the transaction and wait for the transfer to be processed on Greenfield.

    5. Once the transaction is confirmed, the funds will be transferred from Greenfield to BSC. The transferred funds will reflect in the same account on BSC within a few seconds.

    You can also use DCellar and follow How to Transfer Out to transfer BNBs from Greenfield to BSC.

    Note

    One thing to note is if the value of the cross-chain transfer is over 1000BNB, the funds will be locked in TokenHub for 12 hours before they can be withdrawn. Usually, a third-party server will help withdraw the unlocked token to the recipient, and users can also withdraw to the recipient themselves by following unlock document

    "},{"location":"bnb-greenfield/getting-started/token-transfer/#bnb-transfers-in-greenfield","title":"BNB Transfers in Greenfield","text":"

    Greenfield allows for easy and secure transfers between different accounts. However, due to the particularity of the transaction format, it is currently not possible to transfer tokens through the built-in Send function in the wallet, like MetaMask. To conduct an internal transfer within Greenfield, please adhere to the following steps:

    1. Visit DCellar.

    2. Click the Get Started button located at the top right.

    3. Connect your wallet and sign in.

    4. Go to the Wallet page on the left sidebar, then proceed to the Send page.

    5. Fill in the destination address where you want to transfer, specify the amount, and click the Send button.

    6. Confirm the transfer and wait for the transaction to be processed.

    7. Once the transfer is confirmed, the funds will be moved from the source account to the destination account within Greenfield.

    "},{"location":"bnb-greenfield/getting-started/wallet-configuration/","title":"Wallet Configuration - BNB Greenfield","text":""},{"location":"bnb-greenfield/getting-started/wallet-configuration/#wallet-configuration","title":"Wallet Configuration","text":"

    In this guide, you will learn how to use the extension wallets to interact with Greenfield. You can also add BNB Greenfield network according to the RPC Endpoints manually.

    "},{"location":"bnb-greenfield/getting-started/wallet-configuration/#supported-wallets","title":"Supported Wallets","text":"

    We assume you have installed Trust Wallet or MetaMask and have an account, if not, please refer to the download link of Trust Wallet and MetaMask to install it.

    "},{"location":"bnb-greenfield/getting-started/wallet-configuration/#add-greenfield-network","title":"Add Greenfield Network","text":"
    1. Visit BNB Chain List.

    2. Click Connect Wallet.

    1. Find Greenfield Mainnet or Greenfield Testnet, and click Add To Wallet to add new RPC in Trust Wallet or Metamask.

    1. When extension wallet prompts a window, click Approve.

    "},{"location":"bnb-greenfield/roadmap/features/","title":"Feature Lists - BNB Greenfield","text":""},{"location":"bnb-greenfield/roadmap/features/#feature-lists","title":"Feature Lists","text":"

    As a decentralized storage network, Greenfield provides a rich set of features and playability. This article documents the key features and their development status on Greenfield. Please stay tuned.

    Feature Name Description Status Ethereum compatible address Greenfield supports Ethereum compatible address format, which means users can continue to use Ethereum compatible wallets and accounts Mainnet EIP-712 transaction Support structured signature method of EIP-712, making the signed message user-readable Mainnet Governance Validators can vote on proposals through governance, including modification of various module parameters, validator joining and exiting, new SP joining, cross-chain contract parameters, etc. Mainnet Permission staking Support validator joining and exiting through governance, validator delegate/undelegate operations Mainnet Greenfield <-> BSC token transfer Support bidirectional cross-chain token transfer between BSC and Greenfield Mainnet SP basic operations Support new SP joining, viewing current SP, modifying SP information, and updating SP storage prices, etc. Mainnet Bucket operations Support creating/updating/deleting buckets Mainnet Object operations Support creating/uploading/downloading/deleting objects Mainnet Group operations Support creating/updating/deleting groups Mainnet Billing system Users need to pay storage and reading fees for objects stored on Greenfield. SPs earn corresponding income through corresponding storage services. Greenfield uses a stream payment method to calculate fees Mainnet Permission management Greenfield provides rich permission management functions, which can assetize data stored on it and open it to certain users. Greenfield supports adding or deleting permissions for individual users or groups at the bucket and object level Mainnet Resource mirror Greenfield supports mapping buckets, objects, and groups to BSC. There is a unique NFT on BSC corresponding to the data and resources, and developers can build various smart contract cross-chain management of resources on BSC, providing rich playability Mainnet Universal endpoint Users can access files stored on Greenfield through any SP in the SP network Mainnet Folder Greenfield supports prefix queries and delimiter queries for files within buckets, allowing dApps to organize folders on top of Greenfield Mainnet Data challenge Greenfield uses the data challenge scheme as a guarantee of data existence. Greenfield will randomly challenge the data segments stored on SPs. Users can also challenge any data segments stored on SPs to ensure that SPs correctly store their data Mainnet Data recovery Data recovery is used to ensure that the original data can be recovered when certain data is lost on SPs, ensuring the reliability of user data on Greenfield. Greenfield supports various forms of data recovery: 1. Data will be automatically recovered after data challenge succeeds. 2. Data will be automatically recovered when users find that the data is unreadable. 3. SPs can selectively recover some lost data through tools Mainnet Large object and breakpoint resume Greenfield supports breakpoint resume, which improves the efficiency and user experience of object transfer Mainnet SP graceful exit When SPs want to exit voluntarily for some reason, Greenfield can support SPs to migrate the previously stored data to other SPs and then exit, so that the freedom of SPs is ensured without affecting the availability of data on Greenfield Mainnet Migrate bucket Greenfield supports users to migrate their bucket from one SP to another Mainnet Expiration time for group member Greenfield supports setting expired time for group members Mainnet Link with opBNB Build native cross-chain bridge between Greenfield and opBNB Mainnet Resource tags Support setting tags for bucket, object, and group Mainnet Cross-chain permission module Enable add/delete permission from BSC/opBNB smart contracts Mainnet Atomic update Support update object other than delete and create again Testnet Greenfield as DA layer Make Greenfield as the DA layer of the other Blockchains such as opBNB and BSC Design Permanent Storage Support for permanent object storage Design Off Chain Auth Streamline off-chain authentication on Greenfield Mainnet SP as the upload agent Primary Storage Provider acts as the upload agent for object creation on Greenfield Mainnet Greenfield Storage Fee Paymaster A storage fee paymaster solution for sponsors to cover storage costs on Greenfield Mainnet Cross-Chain Programming Improve Greenfield cross-chain programming capability Mainnet"},{"location":"bnb-greenfield/roadmap/roadmap/","title":"Roadmap - BNB Greenfield","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#roadmap","title":"Roadmap","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#march-2023-testnet-congo","title":"March 2023, Testnet Congo","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#may-2023-testnet-mekong","title":"May 2023, Testnet Mekong","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#september-2023-launch-mainnet-lena","title":"September 2023, Launch Mainnet Lena","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#december-2023-mainnet","title":"December 2023, Mainnet","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#march-2024-mainnet","title":"March 2024, Mainnet","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#june-2024-mainnet","title":"June 2024, Mainnet","text":""},{"location":"bnb-greenfield/roadmap/roadmap/#december-2024-mainnet","title":"December 2024, Mainnet","text":"

    For additional information, please refer to the BNB Greenfield Roadmap Proposal.

    "},{"location":"bnb-greenfield/storage-provider/overview/","title":"Overview - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/overview/#overview","title":"Overview","text":""},{"location":"bnb-greenfield/storage-provider/overview/#what-is-the-greenfield-storage-provider","title":"What is the Greenfield Storage Provider","text":"

    Storage Provider (SP) is an infrastructure provider for storage services. They work in synergy with Greenfield validators to provide a complete storage service. Validators store metadata and financial ledgers with consensus, while SPs store the actual data (payload data) of objects using the Greenfield chain as the ledger and single source of truth. SPs provide a range of convenient services for users and dApps to manage data on Greenfield.

    "},{"location":"bnb-greenfield/storage-provider/overview/#how-the-greenfield-storage-providers-works","title":"How the Greenfield Storage Providers works","text":"

    SPs need to register themselves firstly by depositing on the Greenfield blockchain as their Service Stake. The Greenfield validators will then conduct a governance procedure to vote to elect the SPs. When joining and leaving the network, SPs must follow specific actions to ensure data redundancy for users, or they will face fines on their Service Stake.

    SPs provide publicly accessible APIs that allow users to upload, download and manage data. These APIs are designed to be similar to Amazon S3 APIs, making it easier for existing developers to write code for them. SPs are responsible for responding to user requests to write (upload) and read (download) data, as well as managing user permissions and authentications.

    Each SP maintains its own local full node, allowing for a strong connection with the Greenfield network. This enables the SP to directly monitor state changes, properly index data, send transaction requests in a timely manner and manage local data accurately.

    To encourage SPs to showcase their capabilities and provide a professional storage system with high-quality SLA, it is recommended that they advertise their information and prove to the community.

    "},{"location":"bnb-greenfield/storage-provider/overview/#architecture","title":"Architecture","text":"Storage Provider Architecture

    SP contains fifteen core modules as shown below:

    "},{"location":"bnb-greenfield/storage-provider/overview/#how-to-implement-customized-requirements-in-greenfield-sp","title":"How to implement customized requirements in Greenfield SP","text":"

    From the code level, SP is not only an implementation layer, it has been expanded into a framework called GfSp, which allows users to implement their own logics according to their own needs. If users want to implement some specific functions, you can override these methods that are declared in the abstract interfaces. If users don\u2019t need to implement customized requirements, GfSp will use default implementations. There are nine important layers of abstraction:

    "},{"location":"bnb-greenfield/storage-provider/standard/","title":"Data Service Quality Standard - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/standard/#data-service-quality-standard","title":"Data Service Quality Standard","text":""},{"location":"bnb-greenfield/storage-provider/standard/#abstract","title":"Abstract","text":"

    BNB Greenfield is a decentralized storage network comprising two layers: blockchain and storage providers(SPs). The BNB Greenfield blockchain maintains ledgers for users and records storage metadata as common blockchain state data. SPs refer to storage service infrastructures provided by organizations or individuals.

    This standard aims to ensure SPs on Greenfield can provide enterprise-level, secure, reliable, and high-quality storage infrastructure and services to users. SPs that fail to meet the standards may have their eligibility and access revoked from the network.

    The standards consist of two parts:

    In addition to these standards, this document will introduce an official implementation of the SP protocols. Community developers are welcome to:

    "},{"location":"bnb-greenfield/storage-provider/standard/#minimum-service-quality-standards","title":"Minimum Service Quality Standards","text":""},{"location":"bnb-greenfield/storage-provider/standard/#capacity","title":"Capacity","text":""},{"location":"bnb-greenfield/storage-provider/standard/#availability","title":"Availability","text":"

    Greenfield will punish unavailable or poor quality SPs through challenge mechanisms. SPs with SLA below 99.9% or data durability below 99.99% are likely to be phased out.

    In the early stages of Greenfield, to encourage more inexperienced SPs to participate, Greenfield will apply a relatively relaxed slash mechanism to protect SPs from slashing more than 1 BNB within one hour.

    "},{"location":"bnb-greenfield/storage-provider/standard/#scalabilitybetter-to-have","title":"Scalability(better to have)","text":"

    We encourage SPs to dynamically scale up capacity on the basis of providing minimum capacity to avoid being unable to provide services due to sudden traffic and being slashed. The scaling strategy is related to the computing resource platform chosen by the SP. We do not make specific requirements in this regard.

    "},{"location":"bnb-greenfield/storage-provider/standard/#storage-provider-protocols","title":"Storage Provider Protocols","text":""},{"location":"bnb-greenfield/storage-provider/standard/#http-restful-api-specification","title":"HTTP RESTful API Specification","text":"

    Supporting the Greenfield Network API is essential for storage providers. It allows users and developers to interact and integrate with each SP node through a unified interface without having to adapt to custom interfaces from different SP nodes, greatly simplifying the user experience and development difficulty. The API includes functions to retrieve storage space information, upload and download files, and manage permissions.

    SP nodes can implement compatibility with the network API based on their own technology. Developers can refer to the Greenfield Network\u2019s open API documentation for interfacing development.

    "},{"location":"bnb-greenfield/storage-provider/standard/#universal-endpoint","title":"Universal Endpoint","text":"

    All storage objects in the Greenfield Network can be identified and accessed through a universal resource identifier (URI). When creating a storage object, the SP node needs to assign it a unique URI according to the network rules and support using that URI to retrieve the object.

    The detailed spec is defined here.

    "},{"location":"bnb-greenfield/storage-provider/standard/#auth-methods","title":"Auth Methods","text":"

    Permission management and authentication mechanisms are essential for a decentralized storage network, ensuring that only authorized users can access specific storage objects. The Greenfield Network defines standard permission divisions and authorization processes, requiring SP nodes to implement detailed permission control and user authentication accordingly. SP should achieve following three authentication at least:

    "},{"location":"bnb-greenfield/storage-provider/standard/#open-source-implementation","title":"Open source Implementation","text":"

    The open source storage provider framework implements the Greenfield storage provider API and protocol specifications. It provides standardized interfaces and abstractions for SP node developers, greatly reducing the difficulty of setting up a storage provider. Developers can quickly build SP based on this framework and conduct secondary development according to their business needs. This helps cultivate the developer ecosystem of the Greenfield Network and encourages more technical teams to join the construction of the Greenfield Network. Refer to the GitHub repo for more details.

    "},{"location":"bnb-greenfield/storage-provider/standard/#interfaces","title":"Interfaces","text":""},{"location":"bnb-greenfield/storage-provider/standard/#modules","title":"Modules","text":""},{"location":"bnb-greenfield/storage-provider/standard/#minimal-hardware-requirement","title":"Minimal Hardware Requirement","text":""},{"location":"bnb-greenfield/storage-provider/standard/#secondary-development-examples","title":"Secondary Development Examples","text":"

    Customize interface

    // new your own CustomizedPieceStore instance that implement the PieceStore interface\npieceStore := NewCustomizedPieceStore(...)\n\n// new GfSp framework app\ngfsp, err := NewGfSpBaseApp(GfSpConfig, CustomizePieceStore(pieceStore))\nif err != nil {\n    return err\n}\n\ngfsp.Start(ctx)\n\n// the GfSp framework will replace the default PieceStore with CustomizedPieceStore\n

    Customize module

    // new your own CustomizedApprover instance that implement the Approver interface\n// NewCustomizedApprover must be func type: \n// func(app *GfSpBaseApp, cfg *gfspconfig.GfSpConfig) (coremodule.Modular, error)\napprover := NewCustomizedApprover(GfSpBaseApp, GfSpConfig)\n\n// the Special Modular name is Predefined\ngfspapp.RegisterModularInfo(model.ApprovalModularName, model.ApprovalModularDescription, approver)\n\n// new GfSp framework app\ngfsp, err := NewGfSpBaseApp(GfSpConfig, CustomizeApprover(approver))\nif err != nil {\n    return err\n}\n\ngfsp.Start(ctx)\n// the GfSp framework will replace the default Approver with Customized Approver\n
    "},{"location":"bnb-greenfield/storage-provider/standard/#documents","title":"Documents","text":""},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/","title":"Storage Provider Lifecycle - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#storage-provider-lifecycle","title":"Storage Provider Lifecycle","text":"

    This document describes the entire lifecycle of a storage provider from joining the Greenfield Storage Network to exiting.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#preparation","title":"Preparation","text":"

    First, the storage provider needs to learn how to run and create a storage provider node, which requires several different user accounts and a unified external EndPoint.

    Note

    For more information, please see Run Storage Provider

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#proposal","title":"Proposal","text":"

    The Storage Provider (SP) must initiate an on-chain proposal that outlines the Msg information to be automatically executed after receiving approval through the voting process. Specifically, the Msg in this case is MsgCreateStorageProvider. It\u2019s essential to ensure that the deposit tokens exceed the minimum deposit tokens specified on the chain.

    Below are the required fields that need to be modified in the proposal:

    Note

    For more information, please see Add Storage Provider to Greenfield Network

    Initiating this on-chain proposal with the necessary modifications and deposits is a crucial step for the SP to become an active participant in the Greenfield network, offering reliable and secure storage services to users. By complying with the proposal requirements, the SP can enhance its reputation and attract more users, contributing to the growth and success of the decentralized storage ecosystem.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#in-service","title":"In Service","text":"

    During the in-service status, Storage Providers (SPs) actively engage in the network\u2019s daily operations. They handle a variety of user requests, including data storage, retrieval, and other storage-related operations.

    SPs assume a critical role in maintaining the availability, integrity, and confidentiality of the data they store. As gatekeepers of user access, they enforce proper authentication and authorization procedures to safeguard data from unauthorized access or tampering.

    At this stage, SPs must create virtual groups within the Greenfield network to efficiently serve buckets and objects. These virtual groups, resembling disk sectors, allow SPs to manage data storage in a more organized and optimized manner. By associating objects with virtual groups, SPs can limit the range of secondary storage providers responsible for storing object replica data, which enhances data redundancy and resilience.

    Note

    For more information, please see Virtual Group

    Additionally, SPs are required to provide corresponding stakes for the amount of data they store. This staking mechanism further incentivizes SPs to offer reliable and high-quality services to users. By staking tokens or digital assets, SPs demonstrate their commitment to maintaining a robust and trustworthy network, aligning their interests with the overall security and success of the storage ecosystem.

    Moreover, the creation of virtual groups and staking helps to disentangle the interdependency between buckets/objects and SPs. By doing so, SPs mitigate the need for an extensive volume of transactions when modifying on-chain BucketInfo and ObjectInfo during SP exits and bucket migrations. This leads to more efficient network management and smoother transitions during changes in the network\u2019s composition.

    As SPs continue to serve user needs and actively participate in network operations, their reputation and service quality become paramount. A positive reputation score is crucial for attracting more users to store their data with a particular SP. Through continuous improvement and adaptation, SPs can enhance their services, increase storage capacity, and maintain a competitive edge in the dynamic decentralized storage market.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#in-maintenance","title":"In Maintenance","text":"

    The maintenance mode for service providers (SPs) is a status in which SPs do not serve any create/upload requests from users. There are two circumstances in which an SP can be in maintenance mode:

    1. When an SP joins the network after a proposal has passed, it will stay in STATUS_IN_MAINTENANCE until it sends a transaction including msg MsgUpdateStorageProviderStatus to Greenfield to change its status to STATUS_IN_SERVICE.
    2. If an SP is already in service, it can send a transaction with msg MsgUpdateStorageProviderStatus to Greenfield and request a maintenance duration, if there are no restrictions violated, the SP is allowed to enter maintenance mode immediately.

    Note

    Note: The SP needs to send a transaction to Greenfield to update its status back STATUS_IN_SERVICE before its request duration ends, or Greenfield would do it mandatorily.

    There are two restrictions that apply when an SP requests to be in maintenance. These restrictions work with the parameters num_of_historical_blocks_for_maintenance_records, maintenance_duration_quota and num_of_lockup_blocks_for_maintenance. Refer to Params

    To ensure the quality of service provided, we strongly recommend that SPs conduct a self-test via the maintenance account before turning back to STATUS_IN_SERVICE. This includes creating buckets/objects to verify that all functionalities work as expected. For a detailed illustration on how to use SDK to create bucket/object, please refer to the APIs and SDKs.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#exit","title":"Exit","text":"

    There are two types of exit based on the behavior and choices of the SP: Graceful Exit and Forced Exit.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#graceful-exit","title":"Graceful Exit","text":"

    At some point, the SP may choose to voluntarily exit the Greenfield storage network for various reasons. Ensuring a graceful exit process is crucial to ensure a seamless transition of responsibilities and data to other SPs. During the exit process, the SP must continue to fulfill user serve user querying requests, Once the exit process is successfully completed, the SP can retrieve all the staked BNB.

    To execute a graceful exit, all its stored data need to be migrated to other successor SPs that are willing to take over. This data migration process involves recovering data from the exiting SP by successor SPs in a secure and efficient manner. After the exit SP sending a StorageProviderExit transaction to the Greenfield Blockchain, its status will turn to STATUS_GRACEFUL_EXITING. A successor SP can initiate the recovery process by first sending a ReserveSwapIn transaction to the Greenfield Blockchain, reserving the exit SP\u2019s position in the respective Global Virtual Group (GVG) or GVG Family so that it will be allowed to recover data from other SPs. Once the successor SP successfully takes over all data in a GVG or GVG Family, it will send a CompleteSwapIn transaction to the Greenfield Blockchain, confirming the completion of the data transfer process.

    Greenfield Blockchain incorporates an effective consensus mechanism to facilitate and validate the graceful exit process. This mechanism ensures that the exit is carried out transparently, maintaining the network\u2019s integrity and preventing any disruptions or data loss during the transition.

    To ensure the safe and reliable migration of data, frequent data challenges are applied to the SPs that take over the data. These challenges are designed to verify the integrity and consistency of the migrated data, reassuring users that their data remains secure and accessible.

    "},{"location":"bnb-greenfield/storage-provider/storage-provider-lifecycle/#forced-exit","title":"Forced Exit","text":"

    An uncooperative SP no longer wishes to provide service and refuses to go through the standard graceful exit process. In such a case, Greenfield governance will force the SP to exit, make it enter STATUS_FORCED_EXITING. The data recovery process for successor SP is the same as graceful exit mentioned above. However, a forced exit SP will face penalties, and its staked BNB will be locked into the Payment module governance account, this payment account is used to receive forced settlement fee, and pay for potential debt from late forced settlement.

    Note

    For more information, please see SP exit

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/","title":"SP Common Issues - BNB Greenfield SP","text":"

    This is a list of solutions to common SP deployment issues

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#on-chain-proposal","title":"On-chain Proposal","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#1-why-send-tx-failed","title":"1. Why send tx failed?","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#2-why-is-proposal-rejected","title":"2. Why is Proposal Rejected?","text":"

    If your proposal received less than \u2154 of yes votes from validators, your propoosal will be rejected.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#3-why-is-proposal-failed","title":"3. Why is Proposal Failed","text":"

    To query the failed reason, run the following command:

    #  Greenfield Mainnet\n./gnfd query gov proposal <proposal-id> --node https://greenfield-chain-us.bnbchain.org:443\n\n# Greenfield Testnet\n./gnfd q gov proposal <proposal-id> --node https://gnfd-testnet-fullnode-tendermint-ap.bnbchain.org:443\n

    If you see the following message:

    failed_reason: 'spendable balance 999009992000000000000BNB is smaller than 1000000000000000000000BNB:\n

    It means the proposal initiator should be the funding address, and it should have balance of 1k BNB as deposit, according to above error msg.

    Please note the initial deposit requirement varies on different environments. see funding-address

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#sp-node-issues","title":"SP Node Issues","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#1-address-not-found-issue","title":"1. Address Not Found Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description","title":"Description","text":"

    After starting SP binary, see the following error:

    rpc error: code = NotFound desc = rpc error: code = NotFound desc = account 0x12334567890 not found: key not found\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause","title":"Root Cause","text":"

    It\u2019s not possiible to find information about a newly created address on chain.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution","title":"Solution","text":"

    Before starting your SP, transfer BNB to all of your 5 addresses.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#2-database-configuration-issue","title":"2. Database Configuration Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_1","title":"Description","text":"

    After starting SP binary, see the following error:

    Table \"block_syncer.master_db\" does not exist\nFailed to get db config from config file\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_1","title":"Root Cause","text":"

    Data source name(dsn) is not set in config.toml.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_1","title":"Solution","text":"
    [BlockSyncer]\nModules = ['epoch','bucket','object','payment','group','permission','storage_provider','prefix_tree', 'virtual_group','sp_exit_events','object_id_map','general']\nDsn = [BsDB_User]:[BsDB_Passwd]@tcp([BsDB_Address])/[BsDB_Database?parseTime=true&multiStatements=true&loc=Local&interpolateParams=true\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#3-object-sealed-state-issue","title":"3. Object Sealed State Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_2","title":"Description","text":"

    After uploading a file, you see an error message:

    Message: object has not been sealed state\n

    From SP log, you see the following:

    {\"t\":\"2023-07-10T11:34:50.856+0800\",\"l\":\"error\",\"caller\":\"gfspapp/sign_server.go:42\",\"msg\":\"failed to seal object\",\"error\":\"code_space:\\\"signer\\\" http_status_code:400 inner_code:120002 description:\\\"failed to broadcast seal object tx, error: failed to broadcast tx, resp code: 13\\\" \"}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_2","title":"Root Cause","text":"

    SealAddress does not have enough BNB to sign seal transactions

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_2","title":"Solution","text":"

    Transfer BNB to SealAddress.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#4-p2p-issue","title":"4. P2P Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_3","title":"Description","text":"

    After starging SP binary, you see an error message:

    failed to parse address 'k8s-gftestne-p2pexter-bc25ac70bc-a31e9596d87054c3.elb.us-east-1.amazonaws.com:9933' domain\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_3","title":"Root Cause","text":"

    SP is trying to get connected with invalid SP URL in P2P network

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_3","title":"Solution","text":"

    Update [P2P] setting in config.toml:

    [P2P]\n# p2p node msg Secp256k1 encryption key, it is different from other SP's addresses\nP2PPrivateKey = '${p2p_private_key}'\nP2PAddress = '0.0.0.0:9933'\nP2PAntAddress = '${load_balance_doamin:port}'\nP2PBootstrap = []\nP2PPingPeriod = 0\n

    P2PAntAddress is your load balance address. If you don\u2019t have a load balance address, you should have a public IP and use it in P2PAddress. P2PBootstrap is not used anymore, you can leave this field empty.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#5minio-authentication-issue","title":"5.MinIO Authentication Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_4","title":"Description","text":"

    Cannot config Minio as storage

    {\"t\":\"2023-07-17T18:05:40.245+0800\",\"l\":\"debug\",\"caller\":\"storage/object_storage.go:15\",\"msg\":\"created minio storage at endpoint http://172.17.0.2:9000/hashquark\"}\nJul 17 18:05:41 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:05:40.245+0800\",\"l\":\"info\",\"caller\":\"storage/minio.go:37\",\"msg\":\"new minio store succeeds\",\"bucket\":\"hashquark\"}\nJul 17 18:07:01 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:07:00.893+0800\",\"l\":\"error\",\"caller\":\"storage/s3.go:147\",\"msg\":\"S3 failed to head bucket\",\"error\":\"NoCredentialProviders: no valid providers in chain. Deprecated.\\n\\tFor verbose messaging see aws.Config.CredentialsChainVerboseErrors\"}\nJul 17 18:07:01 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:07:00.893+0800\",\"l\":\"error\",\"caller\":\"piece/piece_store.go:88\",\"msg\":\"failed to head bucket\",\"error\":\"NoCredentialProviders: no valid providers in chain. Deprecated.\\n\\tFor verbose messaging see aws.Config.CredentialsChainVerboseErrors\"}\nJul 17 18:07:01 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:07:00.893+0800\",\"l\":\"error\",\"caller\":\"piece/piece_store.go:77\",\"msg\":\"failed to check bucket due to storage is not configured rightly \",\"error\":\"deny access bucket\",\"object\":\"minio://hashquark/\"}\nJul 17 18:07:01 10-7-46-85 gnfd-sp[18585]: {\"t\":\"2023-07-17T18:07:00.893+0800\",\"l\":\"error\",\"caller\":\"piece/piece_store.go:21\",\"msg\":\"failed to create storage\",\"error\":\"deny access bucket\"}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_4","title":"Root Cause","text":"

    This is a MinIO authentication

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_4","title":"Solution","text":"

    You can refer here.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#6-sp-standard-test-issue","title":"6. SP Standard Test Issue","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#description_5","title":"Description","text":"
    2023/07/26 19:06:03.543395 [INFO] GID 41, Uploading file - object: 2q4l5v4v3z, bucket: sc1bw\ndefault error msg : <html>\n<head><title>413 Request Entity Too Large</title></head>\n<body>\n<center><h1>413 Request Entity Too Large</h1></center>\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\n</body>\n</html>\n{\"level\":\"error\",\"time\":\"2023-07-26T13:06:03-06:00\",\"message\":\"do API error, url: https://sc1bw.gnfd-testnet-sp.epotter-qa.io/2q4l5v4v3z, err: statusCode 413 : code : unknown error  request-id  (Message: <html>\\r\\n<head><title>413 Request Entity Too Large</title></head>\\r\\n<body>\\r\\n<center><h1>413 Request Entity Too Large</h1></center>\\r\\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\\r\\n</body>\\r\\n</html>)\"}\n2023/07/26 19:06:03.543395 [INFO] GID 41, Uploading file - object: 2q4l5v4v3z, bucket: sc1bw\ndefault error msg : <html>\n<head><title>413 Request Entity Too Large</title></head>\n<body>\n<center><h1>413 Request Entity Too Large</h1></center>\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\n</body>\n</html>\n{\"level\":\"error\",\"time\":\"2023-07-26T13:06:03-06:00\",\"message\":\"do API error, url: https://sc1bw.gnfd-testnet-sp.epotter-qa.io/2q4l5v4v3z, err: statusCode 413 : code : unknown error  request-id  (Message: <html>\\r\\n<head><title>413 Request Entity Too Large</title></head>\\r\\n<body>\\r\\n<center><h1>413 Request Entity Too Large</h1></center>\\r\\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\\r\\n</body>\\r\\n</html>)\"}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_5","title":"Root Cause","text":"

    Nginx does not support large file

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_5","title":"Solution","text":"

    Enlarge proxy-boody-size

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#dcellar-integration-issues","title":"DCellar Integration Issues","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#1-no-access-control-allow-origin-header-is-present-on-the-requested-resource","title":"1. No \u2018Access-Control-Allow-Origin\u2019 header is present on the requested resource","text":"

    Error:

    Access to XMLHttpRequest at 'https://fbgtest.gnfd-testnet-sp.fbgx.ai/?read-quota&year-month=2023-07' from origin 'https://dcellar.io' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_6","title":"Solution","text":"

    Add these headers

    Access-Control-Allow-Credentials:\ntrue\nAccess-Control-Allow-Headers:\nAccess-Control-Allow-Headers: DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-MD5,Range,Authorization,X-Gnfd-Content-Sha256,X-Gnfd-Unsigned-Msg,X-Gnfd-Txn-Hash,Date,X-Gnfd-Object-ID,X-Gnfd-Resource,X-Gnfd-Piece-Index,X-Gnfd-Redundancy-Index,Address,X-Gnfd-User-Address,X-Gnfd-App-Domain,X-Gnfd-App-Reg-Nonce,X-Gnfd-Date,X-Gnfd-App-Reg-Public-Key,X-Gnfd-App-Reg-Expiry-Date,X-Gnfd-Expiry-Timestamp\nAccess-Control-Allow-Methods:\nGET, PUT, POST, DELETE, PATCH, OPTIONS\nAccess-Control-Allow-Origin:\n*\nAccess-Control-Expose-Headers:\n*, X-Gnfd-Request-ID,X-Gnfd-Signed-Msg,X-Gnfd-Object-ID,X-Gnfd-Integrity-Hash,X-Gnfd-Piece-Hash\nAccess-Control-Max-Age:\n1728000\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#2-when-an-option-request-is-made-i-get-options-405-method-not-allowed-error","title":"2. when an OPTION request is made, I get OPTIONS 405 (Method Not Allowed) error","text":""},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#root-cause_6","title":"Root cause","text":"

    The 405 Method Not Allowed error occurs when the web server is configured in a way that does not allow you to perform a specific action for a particular URL. It\u2019s an HTTP response status code that indicates that the request method is known by the server but is not supported by the target resource.The 405 Method Not Allowed error occurs when the web server is configured in a way that does not allow you to perform a specific action for a particular URL. It\u2019s an HTTP response status code that indicates that the request method is known by the server but is not supported by the target resource.

    "},{"location":"bnb-greenfield/storage-provider/run-book/common-issues/#solution_7","title":"Solution","text":"

    Your application is likely running on a server using one of these three popular webserver software: Apache, nginx, or Cloudflare. Check your configuration files for your web server software for unintentional redirect or request handling instructions.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/","title":"SP Compiling and Dependencies - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#compile-sp","title":"Compile SP","text":"

    Compilation dependencies:

    # clone source code\ngit clone https://github.com/bnb-chain/greenfield-storage-provider.git\n\ncd greenfield-storage-provider/\n\n# install dependent tools: buf, protoc-gen-gocosmos and mockgen\nmake install-tools\n\n# compile sp\nmake build\n\n# move to build directory\ncd build\n\n# execute gnfd-sp binary file\n./gnfd-sp version\n\n# show the gnfd-sp version information\nGreenfield Storage Provider\n    __                                                       _     __\n    _____/ /_____  _________ _____ ____     ____  _________ _   __(_)___/ /__  _____\n    / ___/ __/ __ \\/ ___/ __  / __  / _ \\   / __ \\/ ___/ __ \\ | / / / __  / _ \\/ ___/\n    (__  ) /_/ /_/ / /  / /_/ / /_/ /  __/  / /_/ / /  / /_/ / |/ / / /_/ /  __/ /\n    /____/\\__/\\____/_/   \\__,_/\\__, /\\___/  / .___/_/   \\____/|___/_/\\__,_/\\___/_/\n    /____/       /_/\n\nVersion : v1.0.0\nBranch  : master\nCommit  : 7e1f56809c5385bf1ea6f41d318ab1419dcb0f86\nBuild   : go1.20.3 darwin arm64 2023-10-08 10:31\n\n# show the gnfd-sp help info\n./gnfd-sp -h\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#note","title":"Note","text":"

    If you\u2019ve already executed make install-tools command in your shell, but you failed to make build and encountered one of the following error messages:

    # error message 1\nbuf: command not found\n# you can execute the following command, assumed that you installed golang in /usr/local/go/bin. Other OS are similar.\nGO111MODULE=on GOBIN=/usr/local/go/bin go install github.com/bufbuild/buf/cmd/buf@v1.25.0\n\n# error message 2\nFailure: plugin gocosmos: could not find protoc plugin for name gocosmos - please make sure protoc-gen-gocosmos is installed and present on your $PATH\n# you can execute the fowllowing command, assumed that you installed golang in /usr/local/go/bin. Other OS are similar.\nGO111MODULE=on GOBIN=/usr/local/go/bin go install github.com/cosmos/gogoproto/protoc-gen-gocosmos@latest\n\n# if you want to execute unit test of sp, you should execute the following command, assumed that you installed golang in /usr/local/go/bin. Other OS are similar.\nGO111MODULE=on GOBIN=/usr/local/go/bin go install go.uber.org/mock/mockgen@latest\n

    Above error messages are due to users don\u2019t set go env correctly. More info users can search GOROOT, GOPATH and GOBIN.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#sp-dependencies","title":"SP Dependencies","text":"

    If a user wants to start SP in local mode or testnet mode, you must prepare SPDB, BSDB and PieceStore dependencies.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#spdb-and-bsdb","title":"SPDB and BSDB","text":"

    SP uses SPDB and BSDB to store some metadata such as object info, object integrity hash, etc. These two DBs now use RDBMS to complete corresponding function.

    Users now can use MySQL or MariaDB to store metadata.The following lists the supported RDBMS:

    1. MySQL
    2. MariaDB

    More types of database such as PostgreSQL or NewSQL will be supported in the future.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#piecestore","title":"PieceStore","text":"

    Greenfield is a decentralized data storage system which uses object storage as the main data storage system. SP encapsulates data storage as PieceStore which provides common interfaces to be compatible with multiple data storage systems. Therefore, if a user wants to join SP or test the function of SP, you must use a data storage system.

    The following lists the supported data storage systems:

    1. AWS S3: An object storage can be used in production environment.
    2. Aliyun OSS: Fully managed object storage service to store and access any amount of data from anywhere.
    3. B2: Backblaze B2 provides unlimited data storage in the cloud at \u2155th the cost of Amazon S3.
    4. MinIO: An object storage can be used in production environment which is compatible with AWS S3.
    5. POSIX Filesystem: Local filesystem is used for experiencing the basic features of SP and understanding how SP works. The piece data created by SP cannot be got within the network and can only be used on a single machine.

    Detailed info about PieceStore, you can refer this doc.

    "},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#install-dependencies","title":"Install Dependencies","text":""},{"location":"bnb-greenfield/storage-provider/run-book/compile-dependences/#install-mysql-in-centos","title":"Install MySQL in CentOS","text":"
    1. Install MySQL yum package
    # 1. Download MySQL yum package\nwget http://repo.mysql.com/mysql57-community-release-el7-10.noarch.rpm\n\n# 2. Install MySQL source\nrpm -Uvh mysql57-community-release-el7-10.noarch.rpm\n\n# 3. Install public key\nrpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022\n\n# 4. Install MySQL server\nyum install -y mysql-community-server\n\n# 5. Start MySQL\nsystemctl start mysqld.service\n\n# 6. Check whether the startup is successful\nsystemctl status mysqld.service\n\n# 7. Get temporary password\ngrep 'temporary password' /var/log/mysqld.log \n\n# 8. Login MySQL through temporary password\n# After you log in with the temporary password, do not perform any other operations. Otherwise, an error will occur. In this case, you need to change the password\nmysql -uroot -p\n\n# 9. change MySQL password rules\nmysql> set global validate_password_policy=0;\nmysql> set global validate_password_length=1;\nmysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'yourpassword';\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/","title":"SP Config - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/run-book/config/#sp-config","title":"SP Config","text":"

    This section gives you a complete config of SP. ./gnfd-sp config.dump will generate a template config.toml.

    # optional\nEnv = ''\n# optional\nAppID = ''\n# optional\nServer = []\n# optional\nGRPCAddress = ''\n\n[SpDB]\n# required\nUser = ''\n# required\nPasswd = ''\n# required\nAddress = ''\n# required\nDatabase = ''\n# optional\nConnMaxLifetime = 0\n# optional\nConnMaxIdleTime = 0\n# optional\nMaxIdleConns = 0\n# optional\nMaxOpenConns = 0\n# optional\nEnableTracePutEvent = false\n\n[BsDB]\n# required\nUser = ''\n# required\nPasswd = ''\n# required\nAddress = ''\n# required\nDatabase = ''\n# optional\nConnMaxLifetime = 0\n# optional\nConnMaxIdleTime = 0\n# optional\nMaxIdleConns = 0\n# optional\nMaxOpenConns = 0\n# optional\nEnableTracePutEvent = false\n\n[PieceStore]\n# required\nShards = 0\n\n[PieceStore.Store]\n# required\nStorage = ''\n# optional\nBucketURL = ''\n# optional\nMaxRetries = 0\n# optional\nMinRetryDelay = 0\n# optional\nTLSInsecureSkipVerify = false\n# required\nIAMType = ''\n\n[Chain]\n# required\nChainID = ''\n# required\nChainAddress = []\n# optional\nSealGasLimit = 0\n# optional\nSealFeeAmount = 0\n# optional\nRejectSealGasLimit = 0\n# optional\nRejectSealFeeAmount = 0\n# optional\nDiscontinueBucketGasLimit = 0\n# optional\nDiscontinueBucketFeeAmount = 0\n# optional\nCreateGlobalVirtualGroupGasLimit = 0\n# optional\nCreateGlobalVirtualGroupFeeAmount = 0\n# optional\nCompleteMigrateBucketGasLimit = 0\n# optional\nCompleteMigrateBucketFeeAmount = 0\n\n[SpAccount]\n# required\nSpOperatorAddress = ''\n# required\nOperatorPrivateKey = ''\n# optional\nFundingPrivateKey = ''\n# required\nSealPrivateKey = ''\n# required\nApprovalPrivateKey = ''\n# required\nGcPrivateKey = ''\n# required\nBlsPrivateKey = ''\n\n[Endpoint]\n# required\nApproverEndpoint = ''\n# required\nManagerEndpoint = ''\n# required\nDownloaderEndpoint = ''\n# required\nReceiverEndpoint = ''\n# required\nMetadataEndpoint = ''\n# required\nUploaderEndpoint = ''\n# required\nP2PEndpoint = ''\n# required\nSignerEndpoint = ''\n# required\nAuthenticatorEndpoint = ''\n\n[Approval]\n# optional\nBucketApprovalTimeoutHeight = 0\n# optional\nObjectApprovalTimeoutHeight = 0\n# optional\nReplicatePieceTimeoutHeight = 0\n\n[Bucket]\n# optional\nAccountBucketNumber = 0\n# optional\nMaxListReadQuotaNumber = 0\n# optional\nMaxPayloadSize = 0\n\n[Gateway]\n# required\nDomainName = ''\n# required\nHTTPAddress = ''\n\n[Executor]\n# optional\nMaxExecuteNumber = 0\n# optional\nAskTaskInterval = 0\n# optional\nAskReplicateApprovalTimeout = 0\n# optional\nAskReplicateApprovalExFactor = 0.0\n# optional\nListenSealTimeoutHeight = 0\n# optional\nListenSealRetryTimeout = 0\n# optional\nMaxListenSealRetry = 0\n# optional\nMaxObjectMigrationRetry = 0\n# optional\nObjectMigrationRetryTimeout = 0\n# optional\nEnableSkipFailedToMigrateObject = false\n# optional\nBucketTrafficKeepTimeDay = 0\n# optional\nReadRecordKeepTimeDay = 0\n# optional\nReadRecordDeleteLimit = 0\n\n[P2P]\n# optional\nP2PPrivateKey = ''\n# optional\nP2PAddress = ''\n# optional\nP2PAntAddress = ''\n# optional\nP2PBootstrap = []\n# optional\nP2PPingPeriod = 0\n\n[Parallel]\n# optional\nGlobalCreateBucketApprovalParallel = 0\n# optional\nGlobalCreateObjectApprovalParallel = 0\n# optional\nGlobalMaxUploadingParallel = 0\n# optional\nGlobalUploadObjectParallel = 0\n# optional\nGlobalReplicatePieceParallel = 0\n# optional\nGlobalSealObjectParallel = 0\n# optional\nGlobalReceiveObjectParallel = 0\n# optional\nGlobalRecoveryPieceParallel = 0\n# optional\nGlobalMigrateGVGParallel = 0\n# optional\nGlobalBackupTaskParallel = 0\n# optional\nGlobalDownloadObjectTaskCacheSize = 0\n# optional\nGlobalChallengePieceTaskCacheSize = 0\n# optional\nGlobalSyncConsensusInfoInterval = 0\n# optional\nGlobalGCObjectParallel = 0\n# optional\nGlobalGCBucketMigrationParallel = 0\n# optional\nGlobalGCZombieParallel = 0\n# optional\nGlobalGCMetaParallel = 0\n# optional\nUploadObjectParallelPerNode = 0\n# optional\nReceivePieceParallelPerNode = 0\n# optional\nDownloadObjectParallelPerNode = 0\n# optional\nChallengePieceParallelPerNode = 0\n# optional\nAskReplicateApprovalParallelPerNode = 0\n# optional\nQuerySPParallelPerNode = 0\n# required\nDiscontinueBucketEnabled = false\n# optional\nDiscontinueBucketTimeInterval = 0\n# required\nDiscontinueBucketKeepAliveDays = 0\n# optional\nLoadReplicateTimeout = 0\n# optional\nLoadSealTimeout = 0\n\n[Task]\n# optional\nUploadTaskSpeed = 0\n# optional\nDownloadTaskSpeed = 0\n# optional\nReplicateTaskSpeed = 0\n# optional\nReceiveTaskSpeed = 0\n# optional\nSealObjectTaskTimeout = 0\n# optional\nSealObjectTaskRetry = 0\n# optional\nReplicateTaskRetry = 0\n# optional\nReceiveConfirmTaskRetry = 0\n# optional\nGcObjectTaskTimeout = 0\n# optional\nGcZombieTaskTimeout = 0\n# optional\nGcMetaTaskTimeout = 0\n# optional\nGcObjectTaskRetry = 0\n# optional\nGcZombieTaskRetry = 0\n# optional\nGcMetaTaskRetry = 0\n\n[Monitor]\n# required\nDisableMetrics = false\n# required\nDisablePProf = false\n# required\nDisableProbe = false\n# required\nMetricsHTTPAddress = ''\n# required\nPProfHTTPAddress = ''\n# required\nProbeHTTPAddress = ''\n\n# optional\n[Rcmgr]\n# optional\nDisableRcmgr = false\n\n[Log]\n# optional\nLevel = ''\n# optional\nPath = ''\n\n[BlockSyncer]\n# required\nModules = ['epoch','bucket','object','payment','group','permission','storage_provider','prefix_tree','virtual_group','sp_exit_events','object_id_map','general']\n# required\nWorkers = 0\n# optional\nBsDBWriteAddress = ''\n\n[APIRateLimiter]\n# every line should represent one entry of gateway route. The comment after each line must contain which route name it represents.\n# Most of APIs has a qps number, offered by QA team.  That usually means the max qps for the whole 4 gateway cluster.\n# How to setup the RateLimit value, it is a sophistcated question and need take a lot of factors into account.\n# 1. For most query-APIs, we can setup a rate limit up to the 1/4 of max qps, as the config is for only one gateway instance.\n# 2. Also we avoid to setup a too large or too small rate limit value.\n# 3. For upload/download APIs, it is diffiult to use a rate limit as a protect mechanism for the servers. Because the performance of upload/download interactions usually dependens on how large the file is processed.\n# 4. We tetatively setup 50~75 as the rate limit for the download/upload APIs and we can ajdust them once we have a better experience.\n# 5. Currently, please only put one name inside the name list of PathPatttern\n\n# optional\nPathPattern = [\n  {Key = \"/auth/request_nonce\", Method = \"GET\", Names = [\"GetRequestNonce\"]},\n  {Key = \"/auth/update_key\", Method = \"POST\", Names = [\"UpdateUserPublicKey\"]},\n  {Key = \"/permission/.+/[^/]*/.+\", Method = \"GET\", Names = [\"VerifyPermission\"]},\n  {Key = \"/greenfield/admin/v1/get-approval\", Method = \"GET\", Names = [\"GetApproval\"]},\n  {Key = \"/greenfield/admin/v1/challenge\", Method = \"GET\", Names = [\"GetChallengeInfo\"]},\n  {Key = \"/greenfield/admin/v2/challenge\", Method = \"GET\", Names = [\"GetChallengeInfo\"]},\n  {Key = \"/greenfield/receiver/v1/replicate-piece\", Method = \"PUT\", Names = [\"ReplicateObjectPiece\"]},\n  {Key = \"/greenfield/recovery/v1/get-piece\", Method = \"GET\", Names = [\"RecoveryPiece\"]},\n  {Key = \"/greenfield/migrate/v1/notify-migrate-swap-out-task\", Method = \"POST\", Names = [\"NotifyMigrateSwapOut\"]},\n  {Key = \"/greenfield/migrate/v1/migrate-piece\", Method = \"GET\", Names = [\"MigratePiece\"]},\n  {Key = \"/greenfield/migrate/v1/migration-bucket-approval\", Method = \"GET\", Names = [\"MigrationBucketApproval\"]},\n  {Key = \"/greenfield/migrate/v1/get-swap-out-approval\", Method = \"GET\", Names = [\"SwapOutApproval\"]},\n  {Key = \"/download/[^/]*/.+\", Method = \"GET\", Names = [\"DownloadObjectByUniversalEndpoint\"]},{Key = \"/download\", Method = \"GET\", Names = [\"DownloadObjectByUniversalEndpoint\"]},\n  {Key = \"/view/[^/]*/.+\", Method = \"GET\", Names = [\"ViewObjectByUniversalEndpoint\"]},{Key = \"/view\", Method = \"GET\", Names = [\"ViewObjectByUniversalEndpoint\"]},\n  {Key = \"/status\", Method = \"GET\", Names = [\"GetStatus\"]},\n  {Key = \"/.+/.+[?]offset.*\", Method = \"POST\", Names = [\"ResumablePutObject\"]},\n  {Key = \"/.+/.+[?]upload-context.*\", Method = \"GET\", Names = [\"QueryResumeOffset\"]},\n  {Key = \"/.+/.+[?]upload-progress.*\", Method = \"GET\", Names = [\"QueryUploadProgress\"]},\n  {Key = \"/.+/.+[?]bucket-meta.*\", Method = \"GET\", Names = [\"GetBucketMeta\"]},\n  {Key = \"/.+/.+[?]object-meta.*\", Method = \"GET\", Names = [\"GetObjectMeta\"]},\n  {Key = \"/.+/.+[?]object-policies.*\", Method = \"GET\", Names = [\"ListObjectPolicies\"]},\n  {Key = \"/.+[?]read-quota.*\", Method = \"GET\", Names = [\"GetBucketReadQuota\"]},\n  {Key = \"/.+[?]list-read-quota.*\", Method = \"GET\", Names = [\"ListBucketReadRecord\"]},\n  {Key = \"/[?].*group-query.*\", Method = \"GET\", Names = [\"GetGroupList\"]},\n  {Key = \"/[?].*objects-query.*\", Method = \"GET\", Names = [\"ListObjectsByIDs\"]},\n  {Key = \"/[?].*buckets-query.*\", Method = \"GET\", Names = [\"ListBucketsByIDs\"]},\n  {Key = \"/[?].*verify-id.*\", Method = \"GET\", Names = [\"VerifyPermissionByID\"]},\n  {Key = \"/[?].*user-groups.*\", Method = \"GET\", Names = [\"GetUserGroups\"]},\n  {Key = \"/[?].*group-members.*\", Method = \"GET\", Names = [\"GetGroupMembers\"]},\n  {Key = \"/[?].*owned-groups.*\", Method = \"GET\", Names = [\"GetUserOwnedGroups\"]},\n\n  {Key = \"/.+/$\", Method = \"GET\", Names = [\"ListObjectsByBucket\"]},\n  {Key = \"/.+/[?].*\", Method = \"GET\", Names = [\"ListObjectsByBucket\"]},\n  {Key = \"/.+/.+\", Method = \"GET\", Names = [\"GetObject\"]},\n  {Key = \"/.+/.+\", Method = \"PUT\", Names = [\"PutObject\"]},\n  {Key = \"/$\", Method = \"GET\", Names = [\"GetUserBuckets\"]},\n  {Key = \"/[?].*\", Method = \"GET\", Names = [\"GetUserBuckets\"]},\n\n]\n\nNameToLimit = [\n  {Name = \"GetRequestNonce\", RateLimit = 100, RatePeriod = 'S'}, # requestNonceRouterName 3000qps\n  {Name = \"UpdateUserPublicKey\", RateLimit = 100, RatePeriod = 'S'}, # updateUserPublicKeyRouterName 4000qps\n  {Name = \"VerifyPermission\", RateLimit = 100, RatePeriod = 'S'}, # verifyPermissionRouterName  1200qps\n  {Name = \"GetApproval\", RateLimit = 35, RatePeriod = 'S'}, # approvalRouterName  150qps\n  {Name = \"GetChallengeInfo\", RateLimit = 20, RatePeriod = 'S'}, # getChallengeInfoRouterName, no test data\n  {Name = \"ReplicateObjectPiece\", RateLimit = 1000, RatePeriod = 'S'},  # replicateObjectPieceRouterName, no test data. Internal API among sps, no rate limit is needed.\n  {Name = \"RecoveryPiece\", RateLimit = 1000, RatePeriod = 'S'}, # recoveryPieceRouterName, no test data. Internal API among sps, no rate limit is needed.\n  {Name = \"NotifyMigrateSwapOut\", RateLimit = 10, RatePeriod = 'S'},  # notifyMigrateSwapOutRouterName, no test data. Internal API among sps, no rate limit is needed.\n  {Name = \"MigratePiece\", RateLimit = 10, RatePeriod = 'S'}, # migratePieceRouterName, no test data\n  {Name = \"MigrationBucketApproval\", RateLimit = 10, RatePeriod = 'S'}, # migrationBucketApprovalName, no test data\n  {Name = \"SwapOutApproval\", RateLimit = 10, RatePeriod = 'S'}, # swapOutApprovalName, no test data\n  {Name = \"DownloadObjectByUniversalEndpoint\", RateLimit = 50, RatePeriod = 'S'}, # downloadObjectByUniversalEndpointName, 50qps\n  {Name = \"ViewObjectByUniversalEndpoint\", RateLimit = 50, RatePeriod = 'S'}, # viewObjectByUniversalEndpointName, 50qps\n  {Name = \"GetStatus\", RateLimit = 200, RatePeriod = 'S'},# getStatusRouterName, 2000qps\n  {Name = \"ResumablePutObject\", RateLimit = 30, RatePeriod = 'S'}, # resumablePutObjectRouterName , test data is same as putObject object 10qps\n  {Name = \"QueryResumeOffset\", RateLimit = 30, RatePeriod = 'S'},  # queryResumeOffsetName, test data is same as putObject object 10qps\n  {Name = \"QueryUploadProgress\", RateLimit = 50, RatePeriod = 'S'}, # queryUploadProgressRouterName, test data is same as putObject object 10qps\n  {Name = \"GetBucketMeta\", RateLimit = 100, RatePeriod = 'S'}, # getBucketMetaRouterName, 400qps\n  {Name = \"GetObjectMeta\", RateLimit = 100, RatePeriod = 'S'}, # getObjectMetaRouterName, 400qps\n  {Name = \"ListObjectPolicies\", RateLimit = 200, RatePeriod = 'S'}, # listObjectPoliciesRouterName, 2000qps\n  {Name = \"GetBucketReadQuota\", RateLimit = 200, RatePeriod = 'S'}, # getBucketReadQuotaRouterName\n  {Name = \"ListBucketReadRecord\", RateLimit = 100, RatePeriod = 'S'}, # listBucketReadRecordRouterName\n  {Name = \"GetGroupList\", RateLimit = 200, RatePeriod = 'S'}, # getGroupListRouterName\uff0c similar to getUserGroupsRouterName, 2000qps\n  {Name = \"ListObjectsByIDs\", RateLimit = 200, RatePeriod = 'S'}, # listObjectsByIDsRouterName, 1200qps\n  {Name = \"ListBucketsByIDs\", RateLimit = 200, RatePeriod = 'S'}, # listBucketsByIDsRouterName, 2000qps\n  {Name = \"VerifyPermissionByID\", RateLimit = 200, RatePeriod = 'S'}, # verifyPermissionByIDRouterName, 1200qps\n  {Name = \"GetUserGroups\", RateLimit = 200, RatePeriod = 'S'}, # getUserGroupsRouterName, 2000qps\n  {Name = \"GetGroupMembers\", RateLimit = 200, RatePeriod = 'S'}, # getGroupMembersRouterName, 2000qps\n  {Name = \"GetUserOwnedGroups\", RateLimit = 200, RatePeriod = 'S'}, # getUserOwnedGroupsRouterName, 2000qps\n\n  {Name = \"ListObjectsByBucket\", RateLimit = 75, RatePeriod = 'S'}, # listObjectsByBucketRouterName, 300qps\n  {Name = \"GetObject\", RateLimit = 75, RatePeriod = 'S'}, # getObjectRouterName, 100 qps\n  {Name = \"PutObject\", RateLimit = 75, RatePeriod = 'S'}, # putObjectRouterName, 100 qps\n  {Name = \"GetUserBuckets\", RateLimit = 75, RatePeriod = 'S'}] # getUserBucketsRouterName, 1000 qps\n\nHostPattern = []\n\n[Manager]\n# optional\nEnableLoadTask = false\n# optional\nEnableHealthyChecker = false\n# optional\nSubscribeSPExitEventIntervalMillisecond = 0\n# optional\nSubscribeSwapOutExitEventIntervalMillisecond = 0\n# optional\nSubscribeBucketMigrateEventIntervalMillisecond = 0\n# optional\nGVGPreferSPList = []\n# optional\nSPBlackList = []\n# optional\nEnableTaskRetryScheduler = false\n# optional\nRejectUnsealThresholdSecond = 0\n\n[GC]\n# optional\nGCObjectTimeInterval = 0\n# optional\nGCObjectBlockInterval = 0\n# optional\nGCObjectSafeBlockDistance = 0\n# optional\nEnableGCZombie = false\n# optional\nGCZombieSafeObjectIDDistance = 0\n# optional\nGCZombiePieceTimeInterval = 0\n# optional\nGCZombiePieceObjectIDInterval = 0\n# optional\nEnableGCMeta = false\n# optional\nGCMetaTimeInterval = 0\n\n[Quota]\n# optional\nMonthlyFreeQuota = 0\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#app-info","title":"App info","text":"

    These fields are optional.

    # optional\nEnv = ''\n# optional\nAppID = ''\n# optional\nServer = []\n# optional\nGRPCAddress = ''\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#database","title":"Database","text":"

    To config [SpDB], [BsDB], you have to input the user name, db password,db address and db name in these fields.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#piecestore","title":"PieceStore","text":"

    To config [PieceStore] and [PieceStore.Store], you can read the details in this doc

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#chain-info","title":"Chain info","text":""},{"location":"bnb-greenfield/storage-provider/run-book/config/#spaccount","title":"SpAccount","text":"

    These private keys are generated during wallet setup.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#endpoint","title":"Endpoint","text":"

    [Endpoint] specified the URL of different services.

    For single-machine host (not recommended):

    [Endpoint]\nApproverEndpoint = ''\nManagerEndpoint = ''\nDownloaderEndpoint = ''\nReceiverEndpoint = ''\nMetadataEndpoint = ''\nUploaderEndpoint = ''\nP2PEndpoint = ''\nSignerEndpoint = ''\nAuthenticatorEndpoint = ''\n

    For K8S cluster:

    [Endpoint]\nApproverEndpoint = 'manager:9333'\nManagerEndpoint = 'manager:9333'\nDownloaderEndpoint = 'downloader:9333'\nReceiverEndpoint = 'receiver:9333'\nMetadataEndpoint = 'metadata:9333'\nUploaderEndpoint = 'uploader:9333'\nP2PEndpoint = 'p2p:9333'\nSignerEndpoint = 'signer:9333'\nAuthenticatorEndpoint = 'localhost:9333'\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#p2p","title":"P2P","text":"

    Note

    We don\u2019t use P2P service in mainnet and testnet, so users can ignore P2P items.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#gateway","title":"Gateway","text":"
    [Gateway]\nDomainName = 'region.sp-name.com'\n

    The correct configuration should not include the protocol prefix https://.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#blocksyncer","title":"BlockSyncer","text":"

    Here is block_syncer config. The configuration of BsDBWriteAddress can be the same as the BSDB.Address module here. To enhance performance, you can set up the write database address here and the corresponding read database address in BSDB.

    Modules = ['epoch','bucket','object','payment','group','permission','storage_provider','prefix_tree', 'virtual_group','sp_exit_events','object_id_map','general']\nWorkers = 50\nBsDBWriteAddress = 'localhost:3306'\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#fundingprivatekey","title":"FundingPrivateKey","text":"

    There is no need to write FundingPrivateKey in config.toml. It should be kept in cold wallet for safety.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#rcmgr","title":"Rcmgr","text":"

    ResourceManager manages resources within SP system, tracking and accounting for usage across the stack, from internal components to applications. It also allows for resource usage to be limited based on user-configurable policies. Config schema shows as below:

    message GfSpLimit {\n  int64 memory = 1;\n  int32 tasks = 2;\n  int32 tasks_high_priority = 3;\n  int32 tasks_medium_priority = 4;\n  int32 tasks_low_priority = 5;\n  int32 fd = 6;\n  int32 conns = 7;\n  int32 conns_inbound = 8;\n  int32 conns_outbound = 9;\n}\n\nmessage GfSpLimiter {\n  GfSpLimit system = 1;\n  GfSpLimit transient = 2;\n  map<string, GfSpLimit> service_limit = 3;\n}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#quota","title":"Quota","text":"

    Here is quota config. The configuration of MonthlyFreeQuota define the free quota in each month.It will be reduced when the charge quota is exhausted.

    [Quota]\nMonthlyFreeQuota = 0\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#sp-probe","title":"SP Probe","text":"

    It contains two probes: liveness and readiness probe. If users want to check SP whether is healthy and ready. Users can refer Kubernetes docs to learn related concepts. About detailed SP probe info, users can refer SP probe.

    "},{"location":"bnb-greenfield/storage-provider/run-book/config/#sp-mainnet-recommended-config","title":"SP Mainnet Recommended Config","text":"

    This section shows the config of official in Greenfield, so users can add use similar config:

    # optional\nEnv = \"mainnet\"\n# optional\nServer = []\n# optional\nGRPCAddress = '0.0.0.0:9333'\n\n[SpDB]\n# required\nUser = ''\n# required\nPasswd = ''\n# required\nAddress = '{your_db_address}'\n# required\nDatabase = 'storage_provider_db'\n\n[BsDB]\n# required\nUser = ''\n# required\nPasswd = ''\n# required\nAddress = '{your_db_address}'\n# required\nDatabase = 'block_syncer'\n\n[PieceStore]\n# required\nShards = 0\n\n[PieceStore.Store]\n# required\nStorage = 's3'\n# optional\nBucketURL = '{your_bucker_url}'\n# optional\nMaxRetries = 5\n# optional\nMinRetryDelay = 0\n# optional\nTLSInsecureSkipVerify = false\n# required\nIAMType = 'SA'\n\n[Chain]\n# required\nChainID = 'greenfield_1017-1'\n# required\nChainAddress = ['{your_fullnode_address}']\n\n[SpAccount]\n# required\nSpOperatorAddress = '{your_operator_address}'\n# required\n# OperatorPrivateKey = ''\n# required\n# SealPrivateKey = ''\n# required\n# ApprovalPrivateKey = ''\n# required\n# GcPrivateKey = ''\n\n[Endpoint]\n# required\nApproverEndpoint = 'approver:9333'\n# required\nManagerEndpoint = 'manager:9333'\n# required\nDownloaderEndpoint = 'downloader:9333'\n# required\nReceiverEndpoint = 'receiver:9333'\n# required\nMetadataEndpoint = 'metadata:9333'\n# required\nUploaderEndpoint = 'uploader:9333'\n# required\nP2PEndpoint = 'p2p-service:9333'\n# required\nSignerEndpoint = 'signer:9333'\n# required\nAuthenticatorEndpoint = 'localhost:9333'\n\n[Gateway]\n# required\nDomainName = '{your_domain_name}'\n# required\nHTTPAddress = '0.0.0.0:9033'\n\n[P2P]\n# optional\n#P2PPrivateKey = ''\n# optional\nP2PAddress = '0.0.0.0:9933'\n# optional\nP2PAntAddress = ''\n# optional\nP2PBootstrap = []\n# optional\n# P2PPingPeriod = 0\n\n[Parallel]\n# optional\nDiscontinueBucketEnabled = false\n# optional\nDiscontinueBucketKeepAliveDays = 365\n# optional\nGlobalMaxUploadingParallel = 3072\n# optional\nUploadObjectParallelPerNode = 100\n# optional\nReceivePieceParallelPerNode = 1024\n# optional\nDownloadObjectParallelPerNode = 200\n# optional\nChallengePieceParallelPerNode = 200\n# optional\nAskReplicateApprovalParallelPerNode = 10240\n# optional\nGlobalCreateBucketApprovalParallel = 1024\n# optional\nGlobalCreateObjectApprovalParallel = 1024\n# optional\nGlobalUploadObjectParallel = 1024\n# optional\nGlobalReplicatePieceParallel = 1024\n# optional\nGlobalSealObjectParallel = 1024\n# optional\nGlobalReceiveObjectParallel = 10240\n# optional\nGlobalBackupTaskParallel = 1024\n# optional\nGlobalRecoveryPieceParallel = 1024\n# optional\nGlobalGcObjectSafeBlockDistance = 64\n# optional\nGlobalMigrateGVGParallel = 10\n\n[Monitor]\n# required\nDisableMetrics = false\n# required\nDisablePProf = false\n# required\nDisableProbe = false\n# required\nMetricsHTTPAddress = '0.0.0.0:24367'\n# required\nPProfHTTPAddress = '0.0.0.0:24368'\n# required\nProbeHTTPAddress = '0.0.0.0:24369'\n\n# optional\n[Rcmgr]\n# optional\nDisableRcmgr = false\n# optional\n[Rcmgr.GfSpLimiter]\n# optional\n[Rcmgr.GfSpLimiter.System]\n# optional\nMemory = 4294967296\n# optional\nTasks = 10240\n# optional\nTasksHighPriority = 128\n# optional\nTasksMediumPriority = 1024\n# optional\nTasksLowPriority = 16\n# optional\nFd = 2147483647\n# optional\nConns = 2147483647\n# optional\nConnsInbound = 2147483647\n# optional\nConnsOutbound = 2147483647\n\n[BlockSyncer]\n# required\nModules = ['epoch','bucket','object','payment','group','permission','storage_provider','prefix_tree','virtual_group','sp_exit_events','object_id_map','general']\n# required\nWorkers = 50\n# optional\nBsDBWriteAddress = \"{your_db_address}\"\n\n[APIRateLimiter]\n# every line should represent one entry of gateway route. The comment after each line must contain which route name it represents.\n# Most of APIs has a qps number, offered by QA team.  That usually means the max qps for the whole 4 gateway cluster.\n# How to setup the RateLimit value, it is a sophistcated question and need take a lot of factors into account.\n# 1. For most query-APIs, we can setup a rate limit up to the 1/4 of max qps, as the config is for only one gateway instance.\n# 2. Also we avoid to setup a too large or too small rate limit value.\n# 3. For upload/download APIs, it is diffiult to use a rate limit as a protect mechanism for the servers. Because the performance of upload/download interactions usually dependens on how large the file is processed.\n# 4. We tetatively setup 50~75 as the rate limit for the download/upload APIs and we can ajdust them once we have a better experience.\n# 5. Currently, please only put one name inside the name list of PathPatttern\n\n# optional\nPathPattern = [\n    {Key = \"/auth/request_nonce\", Method = \"GET\", Names = [\"GetRequestNonce\"]},\n    {Key = \"/auth/update_key\", Method = \"POST\", Names = [\"UpdateUserPublicKey\"]},\n    {Key = \"/permission/.+/[^/]*/.+\", Method = \"GET\", Names = [\"VerifyPermission\"]},\n    {Key = \"/greenfield/admin/v1/get-approval\", Method = \"GET\", Names = [\"GetApproval\"]},\n    {Key = \"/greenfield/admin/v1/challenge\", Method = \"GET\", Names = [\"GetChallengeInfo\"]},\n    {Key = \"/greenfield/admin/v2/challenge\", Method = \"GET\", Names = [\"GetChallengeInfo\"]},\n    {Key = \"/greenfield/receiver/v1/replicate-piece\", Method = \"PUT\", Names = [\"ReplicateObjectPiece\"]},\n    {Key = \"/greenfield/recovery/v1/get-piece\", Method = \"GET\", Names = [\"RecoveryPiece\"]},\n    {Key = \"/greenfield/migrate/v1/notify-migrate-swap-out-task\", Method = \"POST\", Names = [\"NotifyMigrateSwapOut\"]},\n    {Key = \"/greenfield/migrate/v1/migrate-piece\", Method = \"GET\", Names = [\"MigratePiece\"]},\n    {Key = \"/greenfield/migrate/v1/migration-bucket-approval\", Method = \"GET\", Names = [\"MigrationBucketApproval\"]},\n    {Key = \"/greenfield/migrate/v1/get-swap-out-approval\", Method = \"GET\", Names = [\"SwapOutApproval\"]},\n    {Key = \"/download/[^/]*/.+\", Method = \"GET\", Names = [\"DownloadObjectByUniversalEndpoint\"]},{Key = \"/download\", Method = \"GET\", Names = [\"DownloadObjectByUniversalEndpoint\"]},\n    {Key = \"/view/[^/]*/.+\", Method = \"GET\", Names = [\"ViewObjectByUniversalEndpoint\"]},{Key = \"/view\", Method = \"GET\", Names = [\"ViewObjectByUniversalEndpoint\"]},\n    {Key = \"/status\", Method = \"GET\", Names = [\"GetStatus\"]},\n    {Key = \"/.+/.+[?]offset.*\", Method = \"POST\", Names = [\"ResumablePutObject\"]},\n    {Key = \"/.+/.+[?]upload-context.*\", Method = \"GET\", Names = [\"QueryResumeOffset\"]},\n    {Key = \"/.+/.+[?]upload-progress.*\", Method = \"GET\", Names = [\"QueryUploadProgress\"]},\n    {Key = \"/.+/.+[?]bucket-meta.*\", Method = \"GET\", Names = [\"GetBucketMeta\"]},\n    {Key = \"/.+/.+[?]object-meta.*\", Method = \"GET\", Names = [\"GetObjectMeta\"]},\n    {Key = \"/.+/.+[?]object-policies.*\", Method = \"GET\", Names = [\"ListObjectPolicies\"]},\n    {Key = \"/.+[?]read-quota.*\", Method = \"GET\", Names = [\"GetBucketReadQuota\"]},\n    {Key = \"/.+[?]list-read-quota.*\", Method = \"GET\", Names = [\"ListBucketReadRecord\"]},\n    {Key = \"/[?].*group-query.*\", Method = \"GET\", Names = [\"GetGroupList\"]},\n    {Key = \"/[?].*objects-query.*\", Method = \"GET\", Names = [\"ListObjectsByIDs\"]},\n    {Key = \"/[?].*buckets-query.*\", Method = \"GET\", Names = [\"ListBucketsByIDs\"]},\n    {Key = \"/[?].*verify-id.*\", Method = \"GET\", Names = [\"VerifyPermissionByID\"]},\n    {Key = \"/[?].*user-groups.*\", Method = \"GET\", Names = [\"GetUserGroups\"]},\n    {Key = \"/[?].*group-members.*\", Method = \"GET\", Names = [\"GetGroupMembers\"]},\n    {Key = \"/[?].*owned-groups.*\", Method = \"GET\", Names = [\"GetUserOwnedGroups\"]},\n\n    {Key = \"/.+/$\", Method = \"GET\", Names = [\"ListObjectsByBucket\"]},\n    {Key = \"/.+/.+\", Method = \"GET\", Names = [\"GetObject\"]},\n    {Key = \"/.+/.+\", Method = \"PUT\", Names = [\"PutObject\"]},\n    {Key = \"/$\", Method = \"GET\", Names = [\"GetUserBuckets\"]},\n\n]\n\nNameToLimit = [\n    {Name = \"GetRequestNonce\", RateLimit = 100, RatePeriod = 'S'}, # requestNonceRouterName 3000qps\n    {Name = \"UpdateUserPublicKey\", RateLimit = 100, RatePeriod = 'S'}, # updateUserPublicKeyRouterName 4000qps\n    {Name = \"VerifyPermission\", RateLimit = 100, RatePeriod = 'S'}, # verifyPermissionRouterName  1200qps\n    {Name = \"GetApproval\", RateLimit = 35, RatePeriod = 'S'}, # approvalRouterName  150qps\n    {Name = \"GetChallengeInfo\", RateLimit = 20, RatePeriod = 'S'}, # getChallengeInfoRouterName, no test data\n    {Name = \"ReplicateObjectPiece\", RateLimit = 1000, RatePeriod = 'S'},  # replicateObjectPieceRouterName, no test data. Internal API among sps, no rate limit is needed.\n    {Name = \"RecoveryPiece\", RateLimit = 1000, RatePeriod = 'S'}, # recoveryPieceRouterName, no test data. Internal API among sps, no rate limit is needed.\n    {Name = \"NotifyMigrateSwapOut\", RateLimit = 10, RatePeriod = 'S'},  # notifyMigrateSwapOutRouterName, no test data. Internal API among sps, no rate limit is needed.\n    {Name = \"MigratePiece\", RateLimit = 10, RatePeriod = 'S'}, # migratePieceRouterName, no test data\n    {Name = \"MigrationBucketApproval\", RateLimit = 10, RatePeriod = 'S'}, # migrationBucketApprovalName, no test data\n    {Name = \"SwapOutApproval\", RateLimit = 10, RatePeriod = 'S'}, # swapOutApprovalName, no test data\n    {Name = \"DownloadObjectByUniversalEndpoint\", RateLimit = 50, RatePeriod = 'S'}, # downloadObjectByUniversalEndpointName, 50qps\n    {Name = \"ViewObjectByUniversalEndpoint\", RateLimit = 50, RatePeriod = 'S'}, # viewObjectByUniversalEndpointName, 50qps\n    {Name = \"GetStatus\", RateLimit = 200, RatePeriod = 'S'},# getStatusRouterName, 2000qps\n    {Name = \"ResumablePutObject\", RateLimit = 30, RatePeriod = 'S'}, # resumablePutObjectRouterName , test data is same as putObject object 10qps\n    {Name = \"QueryResumeOffset\", RateLimit = 30, RatePeriod = 'S'},  # queryResumeOffsetName, test data is same as putObject object 10qps\n    {Name = \"QueryUploadProgress\", RateLimit = 50, RatePeriod = 'S'}, # queryUploadProgressRouterName, test data is same as putObject object 10qps\n    {Name = \"GetBucketMeta\", RateLimit = 100, RatePeriod = 'S'}, # getBucketMetaRouterName, 400qps\n    {Name = \"GetObjectMeta\", RateLimit = 100, RatePeriod = 'S'}, # getObjectMetaRouterName, 400qps\n    {Name = \"ListObjectPolicies\", RateLimit = 200, RatePeriod = 'S'}, # listObjectPoliciesRouterName, 2000qps\n    {Name = \"GetBucketReadQuota\", RateLimit = 200, RatePeriod = 'S'}, # getBucketReadQuotaRouterName\n    {Name = \"ListBucketReadRecord\", RateLimit = 100, RatePeriod = 'S'}, # listBucketReadRecordRouterName\n    {Name = \"GetGroupList\", RateLimit = 200, RatePeriod = 'S'}, # getGroupListRouterName\uff0c similar to getUserGroupsRouterName, 2000qps\n    {Name = \"ListObjectsByIDs\", RateLimit = 200, RatePeriod = 'S'}, # listObjectsByIDsRouterName, 1200qps\n    {Name = \"ListBucketsByIDs\", RateLimit = 200, RatePeriod = 'S'}, # listBucketsByIDsRouterName, 2000qps\n    {Name = \"VerifyPermissionByID\", RateLimit = 200, RatePeriod = 'S'}, # verifyPermissionByIDRouterName, 1200qps\n    {Name = \"GetUserGroups\", RateLimit = 200, RatePeriod = 'S'}, # getUserGroupsRouterName, 2000qps\n    {Name = \"GetGroupMembers\", RateLimit = 200, RatePeriod = 'S'}, # getGroupMembersRouterName, 2000qps\n    {Name = \"GetUserOwnedGroups\", RateLimit = 200, RatePeriod = 'S'}, # getUserOwnedGroupsRouterName, 2000qps\n\n    {Name = \"ListObjectsByBucket\", RateLimit = 75, RatePeriod = 'S'}, # listObjectsByBucketRouterName, 300qps\n    {Name = \"GetObject\", RateLimit = 75, RatePeriod = 'S'}, # getObjectRouterName, 100 qps\n    {Name = \"PutObject\", RateLimit = 75, RatePeriod = 'S'}, # putObjectRouterName, 100 qps\n    {Name = \"GetUserBuckets\", RateLimit = 75, RatePeriod = 'S'}] # getUserBucketsRouterName, 1000 qps\n\nHostPattern = []\n\n[Manager]\n# optional\nEnableLoadTask = true\n# optional\nGVGPreferSPList = [1,2,3,4,5,6,7]\n# optional\nEnableTaskRetryScheduler = true\n\n[Executor]\n# optional\nListenSealRetryTimeout = 30\n\n[Quota]\nMonthlyFreeQuota = 0\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/","title":"Exit Greenfield SP Network - BNB Greenfield SP","text":"

    This guide provides step-by-step instructions for SPs to exit the Greenfield NextWork on the Mainnet or Testnet, along with the necessary actions to be performed by both the exiting SP and the successor SP(s).

    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#how-to-exit-greenfield-network","title":"How to exit Greenfield network","text":"

    When an SP decides to exit the Greenfield network, there are three main steps to go through, involving both the exiting SP and other SPs in the network:

    1. Declare the exit
    2. Data recovery by successor SP(s)
    3. Finalize the exit
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#1-declare-the-exit","title":"1. Declare the exit","text":"

    The exiting SP needs to initiate an StorageProviderExit transaction to Greenfield blockchain, which will turn its status to STATUS_GRACEFUL_EXITING.

    To exit the network, you can use the following commands based on the desired network:

    MainnetTestnet
    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\nchainId = \"greenfield_1017-1\"\n
    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\nchainId = \"greenfield_5600-1\"\n

    Command for storage provider to exit:

    gnfd-sp spExit [command options] [arguments...]\n
    Example:
    ./build/bin/gnfd-sp spExit --config ./config.toml\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#2-data-recovery","title":"2. Data recovery","text":"

    For SPs interested in becoming successors, you need to perform the following data recovery steps:

    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#21-reserveswapin","title":"2.1 ReserveSwapIn","text":"

    The perspective successor SP needs to determine Global Virtual group(GVG) and Global Virtual Group Family(VGF) that exiting SP has, This information can be obtained from GreenfieldScan or by using the provided CLI.

    Usage:

    # List the GVG that the exit SP act as secondary SP\n./gnfd-sp query-gvg-by-sp [command options] [arguments...]\n# List the GVG Family that the exit SP act as primary SP\n./gnfd-sp query-vgf-by-sp [command options] [arguments...]\n
    Example:
    # List the GVG that the exit SP(id=1) act as secondary SP\n./gnfd-sp query-gvg-by-sp --config ./config.toml -sp 1\n# List the GVG Family that the exit SPP(id=1) act as primary SP\n./gnfd-sp query-vgf-by-sp --config ./config.toml -sp 1\n

    Once the successor SP has obtained the necessary information, it needs to reserve the position in the exit SP\u2019s GVG Family or GVG.

    Usage:

    # Reserve the exit SP's position in GVG family or GVG\n./gnfd-sp swapIn [command options] [arguments...]\n

    Example:

    # Reserve the exit SP's(id=1) position in GVG family(id=1)\n./gnfd-sp swapIn --config ./config.toml -f 1 -sp 1\n# Reserve the exit SP's(id=1) position in GVG(id=1)\n./gnfd-sp swapIn --config ./config.toml --gid 1 -sp 1\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#22-data-recovery","title":"2.2 Data Recovery","text":"

    The data recovery process is triggered by the successor SP using the following commands:

    Usage:

    ./gnfd-sp recover-vgf [command options] [arguments...]\n./gnfd-sp recover-gvg [command options] [arguments...]\n
    Example:
    # To recover the exit SP's data in the VGF(id=1) as a primary SP:\n./gnfd-sp recover-vgf --config /config/config.toml -f 1\n# To recover the exit SP's data in the GVG(id=1) as a secondary SP:\n./gnfd-sp swapIn --config ./config.toml --gid 1\n
    Once the recovery job is triggered, it will run in the background in the SP Manager module. The progress can be queried using the following command:

    Usage:

    ./gnfd-sp query-recover-p [command options] [arguments...]\n
    Example:
    # Query the GVG family(id=1) recover progress \n./gnfd-sp recover-vgf --config /config/config.toml -f 1\n# Query the GVG(id=1) recover progress\n./gnfd-sp recover-vgf --config /config/config.toml --gid 1\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#23-completeswapin","title":"2.3 CompleteSwapIn","text":"

    Upon completion of the data recovery process and successful verification, the successor SP needs to send a CompleteSwapIn transaction to the Greenfield blockchain, it will be automatically conducted before the recover process concludes, This will finalize the recovery process and allow the successor SP to take over the position in the GVG Family or GVG.

    Note

    It is crucial to note that under no circumstances should the CompleteSwapIn be triggered manually if the successor SP has not completed the data recovery process but acknowledges it. Doing so may result in data availability challenges and potential loss of funds.

    "},{"location":"bnb-greenfield/storage-provider/run-book/exit-SP-network/#3-finalize-the-exit","title":"3. Finalize the Exit","text":"

    Once the successor SP has completed the data recovery process and taken over the position in the GVG Family or GVG, by checking the GVG statistic of exitting SP, confirm that there are no more GVGs associated with it. Anyone in Greenfield network can send a CompleteStorageProviderExit transaction to the Greenfield blockchain to finalize its exit from the network. Below shows the CLI triggered by exiting SP itself.

    Usage:

    ./gnfd-sp completeSpExit [command options] [arguments...]\n

    Example:

    ./gnfd-sp completeSpExit --config /config/config.toml\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/","title":"Join SP Network - BNB Greenfield SP","text":"

    This guide will help you join SP Network: Mainnet and Testnet.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#prerequisite-for-becoming-a-mainnet-sp","title":"Prerequisite for Becoming a Mainnet SP","text":"

    To ensure the stable provision of data services, Storage Providers must meet specific criteria to join the mainnet. - The SP must join the testnet for a minimum of one month. - The SP must store over 1K files across more than 100 buckets on the testnet. - There were no slash event on the SP in the past week.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#how-to-join-sp-network","title":"How to Join SP Network?","text":"

    Greenfield Blockchain validators are responsible for selecting storage providers. For each on-chain proposal to add new storage provider, there are deposit period for depositing BNB and voting period for validators to make votes. Once the proposal passes, new SP can join the network afterwards.

    You can query the governance parameters here.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#1-submit-proposal","title":"1. Submit Proposal","text":"

    The SP needs to initiate an on-chain proposal that specifies the Msg information to be automatically executed after the vote is approved. In this case, the Msg is MsgCreateStorageProvider. It\u2019s worth noting that the deposit tokens needs to be greater than the minimum deposit tokens specified on the chain.

    MainnetTestnet
    rpcAddr = \"https://greenfield-chain.bnbchain.org:443\"\nchainId = \"greenfield_1017-1\"\n
    rpcAddr = \"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org:443\"\nchainId = \"greenfield_5600-1\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#hot-wallet-manual","title":"Hot Wallet Manual","text":"

    You can use the gnfd command to directly send the transaction for creating a storage provider. To do this, please import the private key of the funding account into the Keystore.

    However, it is not safe to use a hot wallet for Mainnet. Instead, you should refer to the Hardware Wallet Manual for instructions on using a hardware wallet.

    Command for creating storage provider:

    ./build/bin/gnfd tx sp create-storage-provider ./create_storage_provider.json --from {funding_address} --node ${rpcAddr} --chain-id ${chainId} --keyring-backend os\n

    The content for create_storage_provider.json, modify it with the correct values as you need:

    cat ./create_storage_provider.json\n{\n  \"messages\":[\n  {\n    \"@type\":\"/greenfield.sp.MsgCreateStorageProvider\",\n    \"description\":{\n      \"moniker\":\"{moniker}\",\n      \"identity\":\"{identity}\",\n      \"website\":\"{website}\",\n      \"security_contact\":\"{security_contract}\",\n      \"details\":\"{details}\"\n    },\n    \"sp_address\":\"{operator_address}\",\n    \"funding_address\":\"{funding_address}\",\n    \"seal_address\":\"{seal_address}\",\n    \"approval_address\":\"{approval_address}\",\n    \"gc_address\":\"{gc_address}\",\n    \"maintenance_address\":\"{maintenance__address}\",\n    \"endpoint\":\"https://{your_endpoint}\",\n    \"deposit\":{\n      \"denom\":\"BNB\",\n      # Mainnet: 500000000000000000000, Testnet: 1000000000000000000000\n      \"amount\":\"500000000000000000000\"\n    },\n    \"read_price\":\"0.1469890427\",\n    \"store_price\":\"0.02183945725\",\n    \"free_read_quota\": 1073741824,\n    \"creator\":\"0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2\",\n    \"bls_key\":\"{bls_pub_key}\",\n    \"bls_proof\":\"{bls_proof}\"\n  }\n],\n  \"metadata\":\"4pIMOgIGx1vZGU=\",\n  \"title\":\"Create <name> Storage Provider\",\n  \"summary\":\"create <name> Storage Provider\",\n  \"deposit\":\"1000000000000000000BNB\"\n}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#hardware-wallet-manual","title":"Hardware Wallet Manual","text":"

    The gnfd command is not available for connecting with the hardware wallet, so you should use the gnfd-tx-sender to send transactions. Here are the steps:

    1. Generate the transaction data.
      ./build/bin/gnfd tx sp create-storage-provider ./create_storage_provider.json --from {funding_address} --print-eip712-msg-type\n
    2. Visit the gnfd-tx-sender website.
    3. Add your hardware wallet into Metamask, and connect the wallet.
    4. Navigate to the Custom Tx page and fill in the generated transaction data in step1.
    5. Click the Submit button to send the transaction.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#understanding-the-parameters","title":"Understanding the Parameters","text":"

    Note

    You can get the gov module address by this command

    curl -X GET \"https://greenfield-chain-us.bnbchain.org/cosmos/auth/v1beta1/module_accounts/gov\" -H  \"accept: application/json\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#2-deposit-bnb-to-proposal","title":"2. Deposit BNB to Proposal","text":"

    Note

    You can get the mininum deposit for proposal by the above command. Please make sure that the initial deposit is greater than min_deposit when submitting the proposal.

    curl -X GET \"https://greenfield-chain-us.bnbchain.org/cosmos/gov/v1/params/deposit\" -H  \"accept: application/json\"\n

    You can skip this step if the initial deposit amount is greater than the min deposit required by the proposal.

    Each proposal needs to deposit enough tokens to enter the voting phase.

    ./build/bin/gnfd tx gov deposit ${proposal_id} 1BNB --from ${funding_address} --keyring-backend os --node ${rpcAddr} --chain-id ${chainId}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#3-wait-voting-and-check-voting-result","title":"3. Wait Voting and Check Voting Result","text":"

    After submitting the proposal successfully, you must wait for the voting to be completed and the proposal to be approved. It will last 7 days on Mainnet while 1 day on Testnet. Once it has passed and is executed successfully, you can verify that the storage provider has been joined.

    Warning

    Please ensure that the storage provider service is running before it has been joined.

    You can check the on-chain SP information to confirm whether the SP has been successfully created.

    ./build/bin/gnfd query sp storage-providers --node ${rpcAddr}\n

    Alternatively, you can check the proposal to know about its execution status.

    ./build/bin/gnfd query gov proposal ${proposal_id} --node ${rpcAddr}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#4-activate-sp","title":"4. Activate SP","text":""},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#storage-provider-standard-test","title":"Storage Provider Standard Test","text":"

    After the proposal has passed, the status of SP is STATUS_IN_MAINTENANCE. To prevent being slashed due to functional abnormalities, you should first perform a full functional test using the maintenance account. You can refer to the SP standard test.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#update-sp-status","title":"Update SP status","text":"

    Once the testing is completed, you need to send a tx to activate the SP to STATUS_IN_SERVICE.

    gnfd tx sp update-status [sp-address] STATUS_IN_SERVICE [flags]\n

    Refer to Maintenance Mode for more details.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#5-sp-address-deposit","title":"5. SP address deposit","text":""},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#funding-address","title":"Funding Address","text":"

    As a new SP, you need deposit a minimum amount of BNB into the funding address. Please note the initial deposit requirement varies on different environments. You can check the sp.params.min_deposit value (in wei BNB) from genesis endpoint response of Greenfield testnet/mainnet. By the time when this doc is written,

    In addition, to join the network in Step 2, an SP must initiate a proposal using a funding address and stake 1 BNB to enter the voting phase. After the voting concludes, the 1 BNB will be refunded to the original account. Therefore, it is advisable for the Funding Address to reserve an additional >1 BNB to cover these costs.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#operator-address","title":"Operator Address","text":"

    SP operator address will be used to send \u201cCreate Global Virtual Group\u201d, \u201cEdit Storage Provider\u201d, \u201cUpdate Storage Provider Status\u201d and other txs to greenfield chain. So it requires some BNB deposited for transaction fee as well. We recommend SP operator address can hold at least 0.1 BNB but not necessarily as much as possible.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#storage-provider-operations","title":"Storage Provider Operations","text":""},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#editstorageprovider","title":"EditStorageProvider","text":"

    This command is used to edit the information of the SP, including endpoint, description, etc.

    Usage:

    gnfd tx sp edit-storage-provider [sp-address] [flags]\n

    For example, edit the endpoint:

    ./build/bin/gnfd tx sp edit-storage-provider ${operator_address} --endpoint ${new_endpoint} --from ${operator_address} --keyring-backend os --node ${rpcAddr} --chain-id ${chainId}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#update-sp-price","title":"Update SP Price","text":"

    Update the storage provider read, store price and free read quota, if there is no change to a specific value, the current value should also be provided.

    The unit of price is a decimal, which indicates wei BNB per byte per second. E.g. the price is 0.02183945725, means approximately $0.018 / GB / Month. (0.02183945725 * (30 * 86400) * (1024 * 1024 * 1024) * 300 / 10 ** 18 \u2248 0.018, assume the BNB price is 300 USD)

    The free-read-quota unit is bytes, for 1GB free quota, it should be 1073741824.

    Usage:

    gnfd tx sp update-price [sp-address] [read-price] [store-price] [free-read-quota] [flags]\n

    Example:

    ./build/bin/gnfd tx sp update-price ${operator_address} 0.1469890427 0.02183945725 1073741824 --from ${operator_address} --keyring-backend os ---node ${rpcAddr} --chain-id ${chainId}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#update-sp-quota","title":"Update SP Quota","text":"

    Besides the above update-price command, you can also use the gnfd-sp command to update the free read quota for SP. The update.quota command is used to update the free quota of the SP, it will send a transaction to the blockchain to update the free read quota, but keep the storage price and read price unchanged.

    Usage:

    gnfd-sp update.quota [command options] [arguments...]\n

    Example:

    ./build/bin/gnfd-sp update.quota --quota 1073741824 --config ./config.toml\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#recover-sp-objects","title":"Recover SP Objects","text":"

    Besides the above commands, you can also use the gnfd-sp command to recover objects for SP, whether it is the primary or secondary sp of the object. The recover.object command is used to recover an object or objects of the SP, it will send a request to other SPs to get replicate of the object(s) you want to recover.

    Usage:

    gnfd-sp recover.object [command options] [arguments...]\n

    Example:

    ./build/bin/gnfd-sp recover.object --config ./config.toml -b bucket_name -o single_object_name\n./build/bin/gnfd-sp recover.object --config ./config.toml -b bucket_name -l object_name1//_object_name2//object_name3\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#claim-sp-income","title":"Claim SP Income","text":"

    To claim income, a storage provider can use settle cmd to settle income in global virtual group families or global virtual groups. To find the global virtual group families or global virtual groups to settle, a storage provider can use query.primary.sp.income or query.secondary.sp.income of gnfd-sp commands.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#to-query-the-income-of-a-primary-sp","title":"To query the income of a primary sp","text":"

    Usage:

    # query sp's income in global virtual group families\ngnfd-sp query.primary.sp.income --config config.toml --sp.id ${sp_id}\n

    An example of response will look like:

    querying primary sp income details for sp  1\nquery timestamp 1698830787 2023-11-01 17:26:27 +0800 CST\nquery results: [{\"vgf_id\":2,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_1\",\"crud_timestamp\":1698631653,\"netflow_rate\":\"4643666191\",\"static_balance\":\"1093710972008743\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"2018422795287337\"},{\"vgf_id\":13,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_2\",\"crud_timestamp\":1698745565,\"netflow_rate\":\"5452639431\",\"static_balance\":\"38607334626064242\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"39072019463652924\"},{\"vgf_id\":15,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_3\",\"crud_timestamp\":1698573876,\"netflow_rate\":\"1925652979\",\"static_balance\":\"55285141693450020\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"55779863125937889\"},{\"vgf_id\":23,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_4\",\"crud_timestamp\":1698745588,\"netflow_rate\":\"5063874897\",\"static_balance\":\"2339430126330703\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"2770867203680206\"},{\"vgf_id\":246,\"stream_record\":{\"account\":\"primary_sp_virtual_payment_account_address_5\",\"crud_timestamp\":1698667216,\"netflow_rate\":\"59568181\",\"static_balance\":\"19326420423320\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"29070047357671\"}]\n

    The unit of the unsettled income is wei BNB. The first element in above query result array means the sp 1 gets 2018422795287337 wei BNB in vgf_id 2.

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#to-query-the-income-of-a-secondary-sp","title":"To query the income of a secondary sp","text":"
    # query sp's income in global virtual groups\ngnfd-sp query.secondary.sp.income --config config.toml --sp.id ${sp_id}\n

    An exmaple of response will look like:

    querying secondary sp income details for sp  1\nquery timestamp 1698830440 2023-11-01 17:20:40 +0800 CST\nquery results: [{\"gvg_id\":2531,\"stream_record\":{\"account\":\"secondary_sp_virtual_payment_account_address_1\",\"crud_timestamp\":1695347375,\"netflow_rate\":\"22256589564\",\"static_balance\":\"917684637479280\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"13073138794535490\"},{\"gvg_id\":8,\"stream_record\":{\"account\":\"secondary_sp_virtual_payment_account_address_2\",\"crud_timestamp\":1696735440,\"netflow_rate\":\"6698761332\",\"static_balance\":\"24312367733445348\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"6391045453997558\"},{\"gvg_id\":11,\"stream_record\":{\"account\":\"secondary_sp_virtual_payment_account_address_3\",\"crud_timestamp\":1696072153,\"netflow_rate\":\"6832159830\",\"static_balance\":\"15803326565544654\",\"buffer_balance\":\"0\",\"lock_balance\":\"0\",\"frozen_netflow_rate\":\"0\"},\"income\":\"5774730701092644\"}\n    ...\n]\n
    The unit of the unsettled income is wei BNB. The first element in above query result array means the sp 1 gets 13073138794535490 wei BNB in gvg_id 2531.
    # settle income in global virtual group family or global virtual groups\ngnfd tx virtualgroup settle [global-virtual-group-family-id] [global-virtual-group-ids] [flags]\n

    Example:

    # query sp's income in global virtual group families\ngnfd-sp query.primary.sp.income --config config.toml --sp.id 1\n
    # query sp's income in global virtual groups\ngnfd-sp query.secondary.sp.income --config config.toml --sp.id 2\n
    # settle income in global virtual group family with id 100\ngnfd tx virtualgroup settle 100 0 [flags]\n\n# settle income in global virtual groups with id 2 or 3 or 4\ngnfd tx virtualgroup settle 0 2,3,4 [flags]\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#tools","title":"Tools","text":"

    SP can use Greenfield Cmd or DCellar to verify its functions:

    "},{"location":"bnb-greenfield/storage-provider/run-book/join-SP-network/#trouble-shooting","title":"Trouble Shooting","text":"

    If you meet issues, please refer to SP common issues.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/","title":"Deploy Piece Store - BNB Greenfield SP","text":"

    Greenfield SP is a storage infrastructure for Greenfield decentralized storgage platform. Greenfield SP uses PieceStore to store users\u2019 payload data.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#piecestore-config","title":"PieceStore Config","text":"

    When creating a PieceStore, there are the following options to configure underlying storage:

    [PieceStore]\n# required\nShards = 0\n\n[PieceStore.Store]\n# required\nStorage = ''\n# optional\nBucketURL = ''\n# optional\nMaxRetries = 0\n# optional\nMinRetryDelay = 0\n# optional\nTLSInsecureSkipVerify = false\n# required\nIAMType = ''\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#shards","title":"Shards","text":"

    When creating a PieceStore, multiple buckets can be defined as the underlying storgae through the Shards option. Based on the sharding, SP can distribute the files to multiple buckets according to the hashed value of the file name. Data sharding technology can distribute the load of concurrent writing of large-scale data to multiple buckets, thereby improving the writing performance.

    The following are points to note when using the data sharding function:

    For example, the following config creates PieceStore with 5 shards.

    [PieceStore]\nShards = 5\n\n[PieceStore.Store]\nStorage = 'minio'\nBucketURL = 'http://10.180.42.161:9000/mybucket%d'\nIAMType = 'AKSK'\n

    After SP initialized through the above command, PieceStore will create 5 buckets named mybucket0, mybucket1, mybucket2, mybucket3 and mybucket4.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#iamtype","title":"IAMType","text":"

    PieceStore supports two authentication modes: AKSK and SA.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#aksk","title":"AKSK","text":"

    In AKSK mode, PieceStore will access object storage by using AccessKeyID and AccessKeySecret. If users use s3 as object storage, you can set AWSAccessKey and AWS_SECRET_KEY into environment variables which are more secure.

    Permanent access credentials generally have two parts, Access Key, Secret Key, while temporary access credentials generally include three parts, Access Key, Secret Key and token, and temporary access credentials have an expiration time, usually between a few minutes and a few hours.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#sa","title":"SA","text":"

    Service Account (abbreviated as SA) is a more secure way for object storage system to authenticate users. In this mode, you needn\u2019t to provide AccessKeyID and AccessKeySecret. If you deploy your SP in Kubernetes, we recommend you using SA to access object storage. AWS S3 can read this documentation to learn how to use SA. Alibaba Cloud OSS uses OIDC to visit OSS safely which users don\u2019t need to provide AccessKeyID and AccessKeySecret.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#how-to-get-temporary-credentials","title":"How to get temporary credentials","text":"

    Different cloud vendors have different acquisition methods. Generally, the Access Key, Secret Key and ARN representing the permission boundary of the temporary access credential are required as parameters to request access to the STS server of the cloud service vendor to obtain the temporary access credential. This process can generally be simplified by the SDK provided by the cloud vendor. For example, Amazon S3 can refer to this link to obtain temporary credentials, and Alibaba Cloud OSS can refer to this link.

    Temporary credentials are also set into environment variables such as s3 by AWS_SESSION_TOKEN, minio by MINIO_SESSION_TOKEN and so on. Due to there is an expiration time in temporary credentials, this is used in test mode.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#supported-storage-type","title":"Supported Storage Type","text":"

    PieceStore now supports the following storage system. If the listed storage systems don\u2019t conatin that you want to use, feel free to submit a requirement issue.

    Name value Amazon S3 s3 Alibaba Cloud OSS oss Backblaze B2 b2 MinIO minio File file Memory memory"},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#amazon-s3","title":"Amazon S3","text":"

    S3 supports two styles of endpoint URI: virtual hosted-style and path-style. The differences are:

    The <region> should be replaced with specific region code, e.g. the region code of US East (N. Virginia) is us-east-1. All the available region codes can be found here. If you use s3 as the underlying storage, you can set Storage = s3 in config.toml.

    AWS S3 AKSK environment variables as follows:

    // AWS_ACCESS_KEY defines env variable name for aws access key\nexport AWS_ACCESS_KEY=\"your_access_key\"\n// AWS_SECRET_KEY defines env variable name for aws secret key\nexport AWS_SECRET_KEY=\"your_secret_key\"\n// AWS_SESSION_TOKEN defines env variable name for aws session token, this is optional\nexport AWS_SESSION_TOKEN=\"your_session_token\"\n

    AWS S3 SA environment variables as follows:

    // AWS_ROLE_ARN defines env variable for aws role arnv\nexport AWS_ROLE_ARN=\"your_role_arn\"\n// AWSSecretKey defines env variable name for aws web identity token file\nexport AWS_WEB_IDENTITY_TOKEN_FILE=\"your_web_identity_token_file\"\n

    Note

    If the S3 bucket has public access (anonymous access is supported), please set export AWS_ACCESS_KEY=\"NoSignRequest\".

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#alibaba-cloud-oss","title":"Alibaba Cloud OSS","text":"

    Please follow this document to learn how to get access key and secret key. Alibaba Cloud also supports using Security Token Service (STS) to authorize temporary access to OSS. If you use OSS as the underlying storage, you can set Storage = oss in config.toml.

    Alibaba Cloud OSS AKSK environment variables as follows:

    // ALIBABA_CLOUD_ACCESS_KEY defines env variable name for OSS access key\nexport ALIBABA_CLOUD_ACCESS_KEY=\"your_access_key\"\n// ALIBABA_CLOUD_SECRET_KEY defines env variable name for OSS secret key\nexport ALIBABA_CLOUD_SECRET_KEY=\"your_secret_key\"\n// ALIBABA_CLOUD_SESSION_TOKEN defines env variable name for OSS session token, this is optional\nexport ALIBABA_CLOUD_SESSION_TOKEN=\"your_session_token\"\n// ALIBABA_CLOUD_OSS_REGION defines env variable name for OSS region\nexport ALIBABA_CLOUD_OSS_REGION=\"oss_region\"\n

    Alibaba Cloud OSS SA environment variables as follows:

    // ALIBABA_CLOUD_ROLE_ARN defines env variable for OSS role arnv\nexport ALIBABA_CLOUD_ROLE_ARN=\"your_role_arn\"\n// ALIBABA_CLOUD_OIDC_TOKEN_FILE defines env variable name for OSS oidc token file\nexport ALIBABA_CLOUD_OIDC_TOKEN_FILE=\"your_oidc_token_file\"\n// ALIBABA_CLOUD_OIDC_PROVIDER_ARN defines env variable for OSS oidc provider arn\nexport ALIBABA_CLOUD_OIDC_PROVIDER_ARN=\"your_oidc_provider_arn\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#backblaze-b2","title":"Backblaze B2","text":"

    To use Backblaze B2 as a storage system for Greenfield SP, you need to create application key firstly. Application Key ID and Application Key respectively corresponds to Access Key and Secret Key. If you use Backblaze B2 as the underlying storage, you can set Storage = b2 in config.toml.

    Backblaze B2 AKSK environment variables as follows:

    // B2_ACCESS_KEY defines env variable name for b2 access key\nexport B2_ACCESS_KEY=\"your_access_key\"\n// B2_SECRET_KEY defines env variable name for b2 secret key\nexport B2_SECRET_KEY=\"your_secret_key\"\n// B2_SESSION_TOKEN defines env variable name for b2 session token\nexport B2_SESSION_TOKEN=\"your_session_token\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#minio","title":"MinIO","text":"

    MinIO is a high-performance, S3 compatible object store. You can visit the official website to learn how to deploy and maintain a MinIO cluster or you can purchase minio service. If you use MinIO as the underlying storage, you can set Storage = minio in config.toml.

    MinIO AKSK environment variables as follows:

    // MINIO_REGION defines env variable name for minio region\nexport MINIO_REGION=\"minio_region\"\n// MINIO_ACCESS_KEY defines env variable name for minio access key\nexport MINIO_ACCESS_KEY=\"your_access_key\"\n// MINIO_SECRET_KEY defines env variable name for minio secret key\nexport MINIO_SECRET_KEY=\"your_secret_key\"\n// MINIO_SESSION_TOKEN defines env variable name for minio session token, this is optional\nexport MINIO_SESSION_TOKEN=\"your_session_token\"\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#file","title":"File","text":"

    When running Greenfield SP in your local machine, you can use local disk to test SP basic functions. The default storage path for root user is /var/piecestore and ~/.piecestore/local for ordinary users in Linux and macOS. In Windows system, the default path is C:/piecestore/local.

    Local storage is usually only used to help users understand how Greenfield SP works and to give users an experience on the basic features of Greenfield SP. The created PieceStore storage can only be used on a single machine. This is not recommended in production environment.

    "},{"location":"bnb-greenfield/storage-provider/run-book/piece-store/#memory","title":"Memory","text":"

    Memory type can be used to test all PieceStore interfaces in memory. It\u2019s convenient for unit test or e2e test.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/","title":"Run SP Node - BNB Greenfield SP","text":"

    This guide helps you set up an SP Node. Once you set up the SP Node successfully, you can follow the Join SP Network guide to make it online.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#prerequisites","title":"Prerequisites","text":""},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#recommended-hardware","title":"Recommended Hardware","text":"

    The following lists the recommended hardware requirements:

    IMPORTANT

    Each storage provider will hold 7 different accounts serving different purposes

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#wallet-preparation","title":"Wallet Preparation","text":"

    There are six accounts below, you can use the below command to generate these accounts:

    ./build/bin/gnfd keys add operator --keyring-backend os\n./build/bin/gnfd keys add seal --keyring-backend os\n./build/bin/gnfd keys add approval --keyring-backend os\n./build/bin/gnfd keys add gc --keyring-backend os\n./build/bin/gnfd keys add maintenance --keyring-backend os\n./build/bin/gnfd keys add bls --keyring-backend os --algo eth_bls\n

    and then export these private keys to prepare for SP deployment:

    ./build/bin/gnfd keys export operator --unarmored-hex --unsafe  --keyring-backend os\n./build/bin/gnfd keys export seal --unarmored-hex --unsafe --keyring-backend os\n./build/bin/gnfd keys export approval --unarmored-hex --unsafe --keyring-backend os\n./build/bin/gnfd keys export gc --unarmored-hex --unsafe --keyring-backend os\n./build/bin/gnfd keys export bls --unarmored-hex --unsafe --keyring-backend os\n

    IMPORTANT

    FundingAddress is used to deposit staking tokens and receive earnings. Therefore, users should prepare your own FundingAddress public key and private key. And keep private key of FundingAddress in cold wallet for safety!

    The private keys of OperatorAddress, SealAddress, ApprovalAddress, GCAddress and BlsAddress can be kept in hot wallet, because they are often used to send transactions.

    If you want to generate public key and private key of FundingAddress in gnfd binary file, you can execute the following commands:

    ./build/bin/gnfd keys add funding --keyring-backend os\n./build/bin/gnfd keys export funding --unarmored-hex --unsafe  --keyring-backend os\n

    maintenance account is not needed for SP deployment, but you should export it to conduct self-test:

    ./build/bin/gnfd keys export maintenance --unarmored-hex --unsafe --keyring-backend os\n

    Please keep these seven private keys safe!

    Moreover, obtain bls public key and generate bls proof to fill in the proposal of creating Storage Provider

    bls_pub_key:

    ./build/bin/gnfd keys show bls --keyring-backend os --output json | jq -r '.pubkey_hex' \n

    bls_proof:

    # Replace the ${bls_pub_key} with the above bls_pub_key to ensure sign the correct bls pub key!!!\n./build/bin/gnfd keys sign \"${bls_pub_key}\" --from bls --keyring-backend os\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#database-configuration","title":"Database Configuration","text":"

    You should create two databases: ${SpDB.Database} and ${BsDB.Database}. Both values can be found in configuration file.

    IMPORTANT

    ${BsDB.Database} requires the utf8mb4_unicode_ci as the character set and collation.

    The following example assumes ${SpDB.Database} as storage_provider_db and ${BsDB.Database} as block_syncer.

    # login in mysql and create database\n# the default encoding for the database should be utf8mb4_unicode_ci\nmysql> CREATE DATABASE storage_provider_db;\nmysql> CREATE DATABASE block_syncer CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n# check the database encoding format\nmysql> show create database block_syncer;\n

    This is the encoding we expect to see

    Database Create Database block_syncer CREATE DATABASE block_syncer /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */"},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#piecestore-configuration","title":"PieceStore Configuration","text":"

    Please follow this doc to config your PieceStore.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#gateway-configuration","title":"Gateway Configuration","text":""},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#1-support-both-path-style-and-virtual-style-routers-in-https-certificates","title":"1. Support both path-style and virtual-style routers in https certificates","text":"

    You need certificates for SP\u2019s exposed gateway service domain name and wildcard subdomain name of it, say you exposed your SP\u2019s gateway service on https://my-sp1.mainnet.dummy-sp.io, then you need SSL certificates for both my-sp1.mainnet.dummy-sp.io and *.my-sp1.mainnet.dummy-sp.io. For instance, if you reqeust AWS ACM certificate, you could request with this:

    Also, route all traffic from both my-sp1.mainnet.dummy-sp.io and *.my-sp1.mainnet.dummy-sp.io to gateway service, for instance, if you use nginx for ingress control, then you\u2019ll need to configure rules look like the following:

    rules:\n  - host: my-sp1.mainnet.dummy-sp.io\n    http:\n      paths:\n        - backend:\n            service:\n              name: gateway # where your SP gateway service is internally, such a k8s service.\n              port:\n                number: 9033\n          path: /\n          pathType: ImplementationSpecific\n  - host: '*.my-sp1.mainnet.dummy-sp.io'\n    http:\n      paths:\n        - backend:\n            service:\n              name: gateway # the same with the above one.\n              port:\n                number: 9033\n          path: /\n          pathType: ImplementationSpecific\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#2-cors-configuration","title":"2. CORS Configuration","text":"

    When working with web applications (e.g. DCellar), SPs need to allow CORS (Cross-Origin Resource Sharing) requests. See: CORS Errors

    If CORS is not configured properly, you may find the DCellar (or any other web applications which mean to interact with your SP) will report CORS errors, similar to below:

    Most people run their SP services behind the nginx or other similar reverse proxies. Usually the CORS settings should be configured in those reverse proxies.

    We recommend SP with reverse proxy can return the following headers:

    access-control-allow-headers: *\naccess-control-allow-methods: *\naccess-control-allow-origin: *\naccess-control-expose-headers: *\n

    After you finish the configuration, you can verify if it works in DCellar.

    1. Go to https://dcellar.io
    2. Press F12 to launch web developer tools and go to \u201cNetwork\u201d tab.
    3. Connect your wallet
    4. Find the \u201cOPTIONS\u201d request to your SP and check its status and response headers. If you see a similar result to the following screenshot, it means your CORS configuration is correct.
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#3-sample-cors-configuration-for-nginx","title":"3. Sample CORS Configuration for Nginx","text":"

    Many storage providers (SPs) prefer to use nginx as their SP\u2019s reverse proxy server. It can also help handle CORS requests.

    Below is a sample nginx config, which can return those expected http response headers about CORS, mentioned in above section. Please note that the nginx servers should explicitly return 204 as response code for http OPTIONS requests.

    server {\n    listen 443;\n    server_name example.com;\n\n    # Cors Preflight methods needs additional options and different Return Code\n    location / {\n        if ($request_method = 'OPTIONS') {\n            add_header 'Access-Control-Allow-Origin' '*';\n            add_header 'Access-Control-Allow-Methods' '*';\n            add_header 'Access-Control-Allow-Headers' '*';\n            add_header 'Access-Control-Max-Age' 1728000;\n            add_header 'Access-Control-Expose-Headers' '*';\n            add_header 'Content-Type' 'text/plain; charset=utf-8';\n            add_header 'Content-Length' 0;\n            return 204;\n        }\n\n        add_header 'Access-Control-Allow-Origin' '*';\n        add_header 'Access-Control-Allow-Methods' '*';\n        add_header 'Access-Control-Allow-Headers' '*';\n        add_header 'Access-Control-Expose-Headers' '*';\n\n        # Rest of your server configuration...\n    }\n}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#4-other-qa-on-nginx-config","title":"4. Other Q&A on Nginx config","text":"

    We observed that some SPs use nginx as their reverse-proxy layer. In this section , we will list some known best practises on nginx config.

    If your nginx uses proxy_pass directive to pass a request to a proxied server (e.g. the SP gateway microservice), you need also use proxy_set_header to set the HOST header. Otherwise, the head of request passed to the SP gateway, will be parsed as 127.0.0.1. In this case, the SP gateway could not verify the signature of the user requests.

    location / {\n  proxy_pass http://127.0.0.1:9033\n  proxy_set_header Host $host;\n}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#create-storage-provider","title":"Create Storage Provider","text":""},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#1-compile-sp","title":"1. Compile SP","text":"

    Follow the Compile SP doc to compile the SP binary or you can download the binary from the Greenfield Storage Provider Release.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#2-sp-config","title":"2. SP Config","text":""},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#generate-config-template","title":"Generate config template","text":"
    cd greenfield-storage-provider/build\n\n# dump default configuration\n./gnfd-sp config.dump\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#write-config","title":"Write config","text":"

    You can learn about how to write your config.toml file here

    It\u2019s recommended to deploy Kubernetes cluster following this guide. The corresonding config file is here.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-SP-node/#3-run-sp","title":"3. Run SP","text":"
    # start sp\n./gnfd-sp --config ${config_file_path}\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/","title":"Run Local SP Network - BNB Greenfield SP","text":"

    This guide helps you to set up a local Greenfield Storage Provider network for testing and other development related purposes.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#recommended-prerequisites","title":"Recommended Prerequisites","text":"

    The following lists the recommended hardware requirements:

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#quickly-setup-local-greenfield-blockchain-network","title":"Quickly setup local Greenfield blockchain network","text":"
    1. Build Greenfield Blockchain

    Note Greenfield blockchain uses a lib which uses cgo, so you should set cgo env var; in addition, you should install gcc compiler in your OS.

    git clone https://github.com/bnb-chain/greenfield.git\ncd greenfield/\nexport CGO_ENABLED=1\nmake build\n

    If you encountered the following error messages while compiling greenfield blockchain, you should install glibc-static and libstdc++-static.

    # command-line-arguments\n/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1\n/bin/ld: cannot find -lstdc++\ncollect2: error: ld returned 1 exit status\n\nmake: *** [build] Error 1\n
    1. Start Greenfield Blockchain
    # 1 validator and 8 storage providers\nbash ./deployment/localup/localup.sh all 1 8\n
    1. Export the keys of SPs
    bash ./deployment/localup/localup.sh export_sps 1 8\n\n# result example\n# {\n#   \"sp0\": {\n#     \"OperatorAddress\": \"0x14539343413EB47899B0935287ab1111Df891d04\",\n#     \"FundingAddress\": \"0x21c6ff21DD7012DE1CCf9055f2eB234A44a1d3fB\",\n#     \"SealAddress\": \"0x8e424c6Db42Ad9A5d91b24e20b5f603eC70abbA3\",\n#     \"ApprovalAddress\": \"0x7Aa5C8B50696f1D15B3A60d6629f7318c605bb4C\",\n#     \"GcAddress\": \"0xfa238a4B262e1dc35c4970A2296A2444B956c9Ca\",\n#     \"MaintenanceAddress\": \"0xbE03316B1D7c3FCB69136e47e02442d6Fb3396dB\",\n#     \"OperatorPrivateKey\": \"ba6e97958d9c43d1ad54923eba99f8d59f54a0c66c78a5dcbc004c5c3ec72f8c\",\n#     \"FundingPrivateKey\": \"bd9d9e7823cd2dc7bc20f1b6676c3025cdda6cf5a8df9b04597fdff42c29af01\",\n#     \"SealPrivateKey\": \"aacd6b834627fdbc5de2bfdb1db31be0ea810a941854787653814c8040a9dd39\",\n#     \"ApprovalPrivateKey\": \"32108ed1a47c0af965824f84ac2162c029f347eec6d0988e642330b0ac264c85\",\n#     \"GcPrivateKey\": \"2fad16031b4fd9facb7dacda3da4ca4dd5f005f4166891bf9f7be13e02abb12d\",\n#     \"MaintenancePrivateKey\": \"cc38f4c004f73a810223776376a37a8ab3ed8204214f5a3a0a2f77f7bb5e2dc1\",\n#     \"BlsPrivateKey\": \"6f349866f18413abb1a78cab947933459042044649686f354e941a646b9ed6e7\"\n#   }\n#   ...\n# }\n

    These JSON data will be used for setup local SP network, so you\u2019d better save it as a json file:

    bash ./deployment/localup/localup.sh export_sps 1 8 > sp.json\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#setup-local-sp-network","title":"Setup local SP network","text":"
    1. Compile SP

    Users who want to compile SP can refer this doc.

    1. Generate localup env

    Use the following instruction to generate template config file, sp.info and db.info in seven different directories. This command is used for generating sp env the first time or regenerating sp env.

    # This command accepts four args, the first arg is json file path that only supports absolute path, the second arg is db user name,\n# the third arg is db password and the fourth arg is db address.\ncd greenfield-storage-provider/\nbash ./deployment/localup/localup.sh --generate json_file_path db_username db_password db_address\n

    The json file path accepted for the first arg is generated by quickly setup local greenfield blockchain network step3.

    View directory structure:

    ls deployment/localup/local_env/sp0\n\u251c\u2500\u2500 sp0\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 config.toml   # generated template config file\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 db.info       # generated db.info is used for config.toml\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 gnfd-sp0      # gnfd-sp binary\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 sp.info       # generated sp.info is used for config.toml\n\u251c\u2500\u2500 sp1\n\u251c\u2500\u2500 ...\n
    # An example for generating local sp env\ncd greenfield-storage-provider/\nbash ./deployment/localup/localup.sh --generate /root/sp.json root greenfield localhost:3306\n\n[root@yourmachine sp0]# cat db.info\n#!/usr/bin/env bash\nUSER=\"root\"                     # database username\nPWD=\"greenfield\"                # database password\nADDRESS=\"localhost:3306\"        # db endpoint, e.g. \"localhost:3306\"\nDATABASE=\"sp_0\"                 # database name\n\n[root@yourmachine sp0]# cat sp.info\n#!/usr/bin/env bash\nSP_ENDPOINT=\"127.0.0.1:9033\"                                                              # gateway endpoint, e.g. \"127.0.0.1:9033\"\nOPERATOR_ADDRESS=\"0x14539343413EB47899B0935287ab1111Df891d04\"                             # OperatorAddr is generated in setup local Greenfield blockchain step 3.\nOPERATOR_PRIVATE_KEY=\"ba6e97958d9c43d1ad54923eba99f8d59f54a0c66c78a5dcbc004c5c3ec72f8c\"   # OperatorPrivKey is generated in setup local Greenfield blockchain step 3.\nFUNDING_PRIVATE_KEY=\"bd9d9e7823cd2dc7bc20f1b6676c3025cdda6cf5a8df9b04597fdff42c29af01\"    # FundingPrivKey is generated in setup local Greenfield blockchain step 3.\nSEAL_PRIVATE_KEY=\"aacd6b834627fdbc5de2bfdb1db31be0ea810a941854787653814c8040a9dd39\"       # SealPrivKey is generated in setup local Greenfield blockchain step 3.\nAPPROVAL_PRIVATE_KEY=\"32108ed1a47c0af965824f84ac2162c029f347eec6d0988e642330b0ac264c85\"   # ApprovalPrivKey is generated in setup local Greenfield blockchain step 3.\nGC_PRIVATE_KEY=\"2fad16031b4fd9facb7dacda3da4ca4dd5f005f4166891bf9f7be13e02abb12d\"         # GcPrivateKey is generated in setup local Greenfield blockchain step 3.\nBLS_PRIVATE_KEY=\"6f349866f18413abb1a78cab947933459042044649686f354e941a646b9ed6e7\"        # BlsPrivateKey is generated in setup local Greenfield blockchain step 3.\n
    1. Start Eight SPs

    Make config.toml according to db.info, sp.info and start eight SPs.

    cd greenfield-storage-provider/\nbash ./deployment/localup/localup.sh --reset\nbash ./deployment/localup/localup.sh --start\n

    The environment directory is as follows:

    deployment/localup/local_env/\n\u251c\u2500\u2500 sp0\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 config.toml    # real config\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 data/          # piecestore data directory\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 db.info\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 gnfd-sp0\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 gnfd-sp.log    # gnfd-sp log file\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 log.txt\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 sp.info\n\u251c\u2500\u2500 sp1\n\u251c\u2500\u2500 ...\n

    Recompile SP

    If you want to modify config.toml in different sp directories or recompile gnfd-sp binary file, you can use the following commands to reset and start local sp:

    cd greenfield-storage-provider/\nbash ./deployment/localup/localup.sh --reset\nbash ./deployment/localup/localup.sh --start\n
    1. Supported commands
    # this command should be executed in greenfield-storage-provider/ directory.\nbash ./deployment/localup/localup.sh --help\n\nUsage: deployment/localup/localup.sh [option...] {help|generate|reset|start|stop|print}\n\n   --help            display help info\n   --generate        generate sp.info and db.info that accepts four args: the first arg is json file path, the second arg is db username, the third arg is db password and the fourth arg is db address\n   --reset           reset env\n   --start           start storage providers\n   --stop            stop storage providers\n   --clean           clean local sp env\n   --print           print sp local env work directory\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#operate-with-sp","title":"Operate With SP","text":"

    If you have already started Greenfield blockchain and Greenfield SP successfully in local, you can use Greenfield Cmd to operate with SP such as CreateBucket, PutObject and GetObject. Detailed info about Greenfield Cmd can be found here.

    Tip

    We strongly recommend you reading Greenfield Cmd. It will help you explore the functions of Greenfield blockchain and SP.

    Next, We provide you a hand by hand tutorial to operate with chain and SP.

    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#1-generate-your-test-account","title":"1. Generate your test account","text":"

    We firstly need to generate a test account and private key:

    cd greenfield/\n# this command will generate a test account whose name is testkey, you can change its name\n./build/bin/gnfd keys add testkey --keyring-backend os\n# export the private key of test account\n./build/bin/gnfd keys export testkey --unarmored-hex --unsafe --keyring-backend os\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#2-transefer-some-bnb-tokens-to-test-account","title":"2. Transefer some BNB tokens to test account","text":"

    After generating test account, there are no any tokens in this account. We should transefer some BNB tokens:

    cd greenfield/\n# transefer 5000 BNB tokens\n./gnfd tx bank send validator0 {generated_test_account_address} 500000000000000000000BNB --home /{your_greenfield_path}/greenfield/deployment/localup/.local/validator0 --keyring-backend test --node http://localhost:26750 -y\n# query your account balances\n./gnfd q bank balances {generated_test_account_address} --node http://localhost:26750\n
    "},{"location":"bnb-greenfield/storage-provider/run-book/run-local-SP-network/#3-use-cmd-to-send-requests","title":"3. Use cmd to send requests","text":"

    If you come in this step, congratulations, you can operate with your own private chain and SP.

    First, we need to configure cmd:

    cd greenfield-cmd/\nmake build\ncd build/\n# generate a keystore file to manage private key information\ntouch key.txt & echo ${TEST_ACCOUNT_PRIVATE_KEY} > key.txt\ntouch password.txt & echo \"test_sp_function\" > password.txt\n./gnfd-cmd --home ./  --passwordfile password.txt account import key.txt \n\n# construct config.toml\ntouch config.toml\n{\n   echo rpcAddr = \\\"http://localhost:26750\\\"\n   echo chainId = \\\"greenfield_9000-121\\\"\n} > config.toml\n

    Second, you can do some operations with SP:

    1. Create bucket
    # list current available SPs\n./gnfd-cmd -c ./config.toml --home ./ sp ls\n# random choose one SP to create bucket\n./gnfd-cmd -c ./config.toml --home ./ bucket create gnfd://${BUCKET_NAME}\n# head bucket info\n./gnfd-cmd -c ./config.toml --home ./ bucket head gnfd://${BUCKET_NAME}\n# choose one sp to create bucket, operator_address is shown in sp ls result\n./gnfd-cmd -c ./config.toml --home ./ bucket create --primarySP ${operator_address} gnfd://${BUCKET_NAME}\n
    1. PutObject & GetObject
    # generate a 17MB random file\ndd if=/dev/urandom of=./random_file bs=17M count=1\n# put object\n./gnfd-cmd -c ./config.toml --home ./ object put --contentType \"application/octet-stream\" ./random_file gnfd://${BUCKET_NAME}/random_file\n# get object\n./gnfd-cmd -c ./config.toml --home ./ object get gnfd://${BUCKET_NAME}/random_file ./new_random_file\n

    Users can use md5 to compare your generated file and downloaded file whether is the same.

    You can explore other functions of Greenfield Cmd.

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/","title":"SP FAQ - BNB Greenfield SP","text":""},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#what-are-requirements-for-greenfield-storage-provider","title":"What are requirements for Greenfield Storage Provider?","text":"

    Storage Providers(SP) should meet the following requirements: * Collateral: * Each SP candidate has to deposit 500 BNB as collateral * SP needs to pledge additional funds to store more data at 200% of the storage fees of the data stored as Primary SP, which is 0.023 * 1024 * 2 = $47.104/TB.

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#how-does-sp-receive-their-rewards","title":"How does SP receive their rewards?","text":"

    SP will receive their rewards in funding address after sending Settlement Transaction.

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#when-to-update-store-price-and-read-price","title":"When to update store price and read price?","text":"

    Every SP can set their own suggested store price and read price via on-chain transactions. Read how to send commands here

    There are some constrains: * When to Update : The global rates will be calculated and updated in each month\u2019s first block (UTC time) by default. * When not Update: By default, SPs cannot update their price in the last two days of the current month.

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#how-much-bnb-is-required-by-sp-to-stake-in-relation-to-how-much-space-they-want-to-provide","title":"How much BNB is required by SP to stake in relation to how much space they want to provide?","text":"

    SP needs to stake additional funds to store user\u2019s data. It\u2019s based on formula: storage_staking_price * stored_size, and the price is now 160000 wei/byte, which could be fetched from this API .

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#whats-the-limit-of-storage-provider-capacity","title":"What\u2019s the limit of Storage Provider capacity?","text":"

    Each VGF serves a limited number of buckets. Once the store size exceeds a specified threshold, the family will no longer allow to serve more buckets. No limit on number of VGF but max size per VGF is 64T

    "},{"location":"bnb-greenfield/storage-provider/run-book/sp-faqs/#how-to-become-a-reliable-sp","title":"How to become a reliable SP?","text":"
    1. Make sure your SP passed this standard test
    2. If your infra is not working, switch your SP back to maintenance mode. Then, back up lost data from secondary SPs.
    "},{"location":"bnb-opbnb/","title":"opBNB - Layer2 Scaling Solution for BSC","text":"opBNB

    opBNB is the Layer 2 scaling solution for the BNB Smart Chain powered by bedrock version of Optimism OP Stack.

    Get Started

    Deposit BNB to opBNB to start your journey

    Summary of opBNB infrastructure

    Run Node

    Run a fullnode on opBNB network

    Build Dapp

    Deploy a simple HelloWorld smart contract on opBNB and build a Web3 frontend

    Multisig Wallet

    Use multi-sig wallet service based on the Gnosis Safe protocol to secure assets and projects

    "},{"location":"bnb-opbnb/overview/","title":"opBNB Overview - opBNB","text":""},{"location":"bnb-opbnb/overview/#opbnb-high-performance-layer-2-solution","title":"opBNB - High-performance layer 2 solution","text":"

    The opBNB network is the Layer 2 scaling solution for the BNB Smart Chain powered by bedrock version of Optimism OP Stack. It works by offloading transaction processing and resource usage from the BNB Smart Chain, while still posting data to the underlying mainnet. Users interact with the opBNB network by depositing funds from BSC and using applications and contracts on opBNB. Sequencers then aggregate transactions, compute state transitions and submit them to the rollup contract on BSC. Provers generate cryptographic proofs that prove the validity of these state transitions, and Verifiers check the proofs to verify the opBNB state is correct. At its core, opBNB allows users to deposit and withdraw funds, use smart contracts, and view network data with high throughput and low fees. By leveraging Layer 2, opBNB is able to scale beyond the constraints of the BNB Smart Chain and provide an improved experience for users.

    "},{"location":"bnb-opbnb/overview/#key-features-and-advantages","title":"Key Features and Advantages","text":"
    1. Optimistic Rollup Technology: opBNB employs Optimistic Rollup, a Layer-2 scaling solution that processes transactions off-chain while maintaining the security of the main BSC chain. By bundling multiple transactions into a single batch and then submitting them to the main chain, Optimistic Rollup reduces the computational load on BSC, resulting in faster and cheaper transactions.

    2. Increased Transaction Throughput: The adoption of Optimistic Rollup allows opBNB to achieve significantly higher transaction throughput compared to the BSC main chain. As of early 2024, opBNB supports up to 5,000 transactions per second (TPS), addressing one of the critical bottlenecks in blockchain scalability.

    3. Lower Transaction Fees: One of the primary benefits of opBNB is the reduction in transaction fees. By processing transactions off-chain and only settling the final state on the BSC main chain, opBNB dramatically lowers the costs associated with executing transactions. This makes it an attractive option for developers and users alike, particularly for micro-transactions and DeFi applications.

    4. Enhanced User Experience: With faster transaction confirmations and lower fees, opBNB significantly enhances the overall user experience. This improvement is crucial for the mass adoption of blockchain technology, as it makes interactions with DApps and DeFi platforms more seamless and affordable.

    5. Robust Security: Despite processing transactions off-chain, opBNB maintains a high level of security by relying on the security model of the underlying BSC main chain. Optimistic Rollup\u2019s fraud-proof mechanism ensures that any invalid transactions can be challenged and corrected, safeguarding the integrity of the network.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/","title":"Full Stack DApp - opBNB","text":""},{"location":"bnb-opbnb/advanced/full-stack-dapp/#create-a-full-stack-dapp-using-truffle-and-react-on-opbnb","title":"Create a Full Stack dapp using Truffle and React on opBNB","text":"

    In this tutorial, we\u2019ll deploy a simple HelloWorld smart contract on opBNB and build a Web3 frontend using React to interact with the deployed smart contract, i.e., read from and write to the opBNB blockchain.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#what-are-we-building","title":"What are we building","text":"

    opBNB is essentially an optimized layer-2 solution that delivers lower fees and higher throughput to unlock the full potential of the BNB Chain.

    For this tutorial, we will deploy a simple HelloWorld smart contract on the opBNB network and build a frontend using Reactjs to interact with the deployed smart contract for reading and writing data onto the opBNB blockchain. The HelloWorld smart contract is a simple string variable message that will be used for storing the user-defined messages, e.g., Hello, opBNB User. The updateMessage function will be used for updating the message variable to any user-defined string value.

    This smart contract will then be deployed on the opBNB network using Truffle IDE. We will then use the Reactjs boilerplate to build a front end to communicate with the smart contract. Web3.js library is used for interacting with the smart contract and reading and writing data to the opBNB blockchain. We further use Metamask for signing transactions and paying any gas costs.

    This is a basic example for educational purposes, and it assumes familiarity with Truffle, React, and MetaMask.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#learning-takeaways","title":"Learning Takeaways","text":"

    By the end of this tutorial, you will be able to achieve the following

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#pre-requisites","title":"Pre-requisites","text":""},{"location":"bnb-opbnb/advanced/full-stack-dapp/#demo-step-by-step-guide","title":"Demo Step-by-Step Guide","text":"

    For this tutorial, we will be using Truffle IDE to develop, compile and deploy a simple HelloWorld smart contract on the opBNB network. For building the front end, we will be using the create-react-app React boilerplate. Further, to connect our dapp to the web3 world, we will be using the Metamask wallet.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step-1-set-up-the-project","title":"Step 1: Set up the project","text":"
    1. Make sure you have Node.js and npm installed on your machine.

    2. Install Truffle globally by running the following command

      npm install -g truffle\n
    3. Create a new directory for your project and navigate into it

      mkdir HelloWorldDapp\ncd HelloWorldDapp\n
    4. Initialize a new Truffle project. Create a bare Truffle project which generates the required directory structure to test and deploy contracts:

      truffle init\n
      Truffle creates the following directory structure for your project:
    5. Install Create React App globally by running the following command

      npm install -g create-react-app\n
    6. Create the React app frontend using the following command

      npx create-react-app frontend\n
    7. Navigate into the client directory using the following command

      cd frontend\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step2-install-hdwallet-provider","title":"Step#2: Install hdwallet-provider\u200b","text":"

    hdwallet-provider is a separate package that signs transactions for addresses derived from a 12 or 24-word mnemonic. By default, the hdwallet-provider uses the first address generated from the mnemonic. However, this is configurable. For more information, refer to the Truffle hdwallet-provider repository. Run the following command to install hdwallet-provider

        npm install @truffle/hdwallet-provider\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step3-create-the-env-file","title":"Step#3: Create the .env file\u200b","text":"
        npm install dotenv\n
    MNEMONIC = \"<Your-MetaMask-Secret-Recovery-Phrase>\";\n

    Never disclose your secret recovery phrase. Anyone with your recovery phrase can steal any assets held in your wallet.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step4-create-the-smart-contract","title":"Step#4: Create the smart contract","text":"

    Inside the contracts directory, create a new file named HelloWorld.sol and add the following code

       // SPDX-License-Identifier: MIT\n   pragma solidity ^0.8.19;\n\n   contract HelloWorld {\n       string public message;\n\n       constructor(string memory _message) {\n           message = _message;\n       }\n\n       function updateMessage(string memory _newMessage) public {\n           message = _newMessage;\n       }\n   }\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step5-configure-truffle-for-use-with-opbnb","title":"Step#5: Configure Truffle for use with opBNB","text":"
    1. Open the truffle-config.js file and add the following code:

      const HDWalletProvider = require(\"@truffle/hdwallet-provider\");\n// create a file at the root of your project and name it .env -- there you can set process variables\n// like the mnemonic etc. Note: .env is ignored by git to keep your private information safe\n\nrequire(\"dotenv\").config();\n\nconst mnemonic = process.env[\"MNEMONIC\"].toString().trim();\n\nmodule.exports = {\n  networks: {\n    development: {\n      host: \"127.0.0.1\", // Localhost (default: none)\n      port: 8545, // Standard Ethereum port (default: none)\n      network_id: \"*\", // Any network (default: none)\n    },\n    opBNBTestnet: {\n      provider: () =>\n        new HDWalletProvider(\n          mnemonic,\n          `https://opbnb-testnet-rpc.bnbchain.org`\n        ),\n      network_id: 5611,\n      confirmations: 3,\n      timeoutBlocks: 200,\n      skipDryRun: true,\n    },\n  },\n\n  // Set default mocha options here, use special reporters etc.\n  mocha: {\n    // timeout: 100000\n  },\n\n  // Configure your compilers\n  compilers: {\n    solc: {\n      version: \"0.8.19\",\n    },\n  },\n};\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step6-deploy-the-smart-contract-on-opbnb","title":"Step#6: Deploy the smart contract on opBNB","text":"
    1. In the root directory of your project, create a new file named 1_deploy_contract.js inside the migrations directory and add the following code:

      const HelloWorld = artifacts.require(\"HelloWorld\");\n\nmodule.exports = function (deployer) {\n  deployer.deploy(HelloWorld, \"Hello, World!\");\n};\n
    2. Deploy the smart contract to the opBNB testnet by running the following command

      truffle migrate --network opBNBTestnet\n

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step7-set-up-the-react-frontend","title":"Step#7: Set up the React frontend","text":"
    1. Inside the frontend/src directory, replace the contents of the App.js file with the following code:

      import React, { useEffect, useState } from \"react\";\nimport Web3 from \"web3\";\nimport HelloWorldContract from \"./contracts/HelloWorld.json\";\nimport \"./App.css\";\n\nfunction App() {\n  const [contract, setContract] = useState(null);\n  const [message, setMessage] = useState(\"\");\n  const [newMessage, setNewMessage] = useState(\"\");\n  const [loading, setLoading] = useState(false);\n\n  useEffect(() => {\n    const loadBlockchainData = async () => {\n      try {\n        const web3 = new Web3(window.ethereum);\n        const networkId = await web3.eth.net.getId();\n        const deployedNetwork = HelloWorldContract.networks[networkId];\n        const instance = new web3.eth.Contract(\n          HelloWorldContract.abi,\n          deployedNetwork && deployedNetwork.address\n        );\n        setContract(instance);\n      } catch (error) {\n        console.error(error);\n      }\n    };\n\n    loadBlockchainData();\n  }, []);\n\n  const getMessage = async () => {\n    if (contract) {\n      try {\n        setLoading(true);\n        const message = await contract.methods.message().call();\n        setMessage(message);\n      } catch (error) {\n        console.error(error);\n      } finally {\n        setLoading(false);\n      }\n    }\n  };\n\n  const updateMessage = async () => {\n    if (contract && newMessage !== \"\") {\n      try {\n        setLoading(true);\n        await contract.methods\n          .updateMessage(newMessage)\n          .send({ from: (await window.ethereum.enable())[0] });\n        setNewMessage(\"\");\n      } catch (error) {\n        console.error(error);\n      } finally {\n        setLoading(false);\n      }\n    }\n  };\n\n  return (\n    <div className=\"App\">\n      <h1 className=\"header\">HelloWorld dApp</h1>\n      <div className=\"content\">\n        <div className=\"message\">\n          <h2>Current Message</h2>\n          <p className=\"messageValue\">{loading ? \"Loading...\" : message}</p>\n          <button onClick={getMessage}>Refresh</button>\n        </div>\n      </div>\n      <div className=\"content\">\n        <div className=\"update\">\n          <h2>Update Message</h2>\n          <input\n            type=\"text\"\n            placeholder=\"New Message\"\n            value={newMessage}\n            onChange={(e) => setNewMessage(e.target.value)}\n            className=\"inputMessage\"\n          />\n          <br />\n          <button onClick={updateMessage}>Update</button>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport default App;\n
    2. Replace the contents of the App.css file with the following code:

      .App {\n  text-align: center;\n}\n\n.header {\n  background-color: #f3ba2f;\n  min-height: 20vh;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  font-size: calc(40px + 2vmin);\n  color: white;\n}\n\n.content {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  padding: auto;\n  text-align: center;\n}\n\n.message,\n.update {\n  padding: auto;\n  margin: 20px;\n}\n.messageValue {\n  color: whitesmoke;\n  font-size: large;\n}\n\n.inputMessage {\n  float: center;\n  padding: 10px;\n  width: 100%;\n  font-family: \"IBM Plex Sans\", \"Raleway\", \"Source Sans Pro\", \"Arial\";\n}\n\nbutton {\n  float: center;\n  margin: 1em 0;\n  padding: 10px 3em;\n  font-weight: bold;\n  max-width: fit-content;\n  font-family: \"IBM Plex Sans\", \"Raleway\", \"Source Sans Pro\", \"Arial\";\n}\n\nbody {\n  background-color: #292929;\n  color: #f3ba2f;\n  align-items: center;\n  font-family: \"IBM Plex Sans\", \"Raleway\", \"Source Sans Pro\", \"Arial\";\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n
    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#step8-start-the-development-server","title":"Step#8: Start the development server","text":"
    1. In the frontend directory, install the required dependencies by running the following command

      npm install\n
    2. Start the React development server:

      npm start\n
    3. Visit http://localhost:3000 in your browser, and you should see the HelloWorld dApp with the current message and the ability to update it.

      Make sure you have the MetaMask extension installed and set to the opBNB testnet.

    4. When you enter a new message and click the update button, if your dapp is already not connected to Metamask wallet, you will get a Metamask notification asking for permission to connect your wallet to the dapp.

    5. It will also ask for your confirmation to confirm the transaction. Proceed by clicking the confirm button.

    6. Once the transaction is confirmed, click the Refresh button to load the new message.

    "},{"location":"bnb-opbnb/advanced/full-stack-dapp/#conclusion","title":"Conclusion","text":"

    In this tutorial, we provided a step-by-step guide on how to develop, deploy, and interact with a smart contract on the opBNB network. We used the Truffle IDE for compiling and deploying the smart contract. We also build a React frontend to interact with the deployed smart contract, i.e., read from and write to the opBNB blockchain.

    "},{"location":"bnb-opbnb/advanced/local-dev-env/","title":"Local Development - opBNB","text":""},{"location":"bnb-opbnb/advanced/local-dev-env/#running-a-local-development-environment","title":"Running a local development environment","text":"

    Install and start the entire opbnb system locally, including L1 (BNB Smart Chain) and L2 development nodes. Running a local development environment is a great way to test the behavior of your code and contracts.

    "},{"location":"bnb-opbnb/advanced/local-dev-env/#how-to-do-it","title":"How to do it","text":"
    1. Make sure the following software is installed: golang, nodejs 16+, make, pnpm, python3, docker, foundry, poetry, jq Tips:

    Install Foundry by following the instructions located here. Please make sure your Foundry version matches the one described in opbnb/versions.json. If they do not match, please use a command such as foundryup -C xxxxxx to modify it.

    1. Clone opbnb monorepo:
        git clone git@github.com:bnb-chain/opbnb.git\n    cd opbnb\n
    1. Running pnpm install and then running pnpm build.
    2. Running make devnet-up and wait for the docker container to start.(The first run will be relatively slow because it needs to download the image and deploy the contract, and then it will be fast)
    3. Through the docker ps command, you can see that 5 containers have been started: ops-bedrock_l1_1, ops-bedrock_l2_1, ops-bedrock_op-node_1, ops-bedrock_op-batcher_1, ops-bedrock_op-proposer_1

    Now L1 is accessible at http://localhost:8545, and L2 is accessible at http://localhost:9545

    "},{"location":"bnb-opbnb/advanced/local-dev-env/#stop-or-clean","title":"Stop or clean","text":"

    To stop, run (in the root directory of the monorepo) make devnet-down. To clean everything, run (in the root directory of the monorepo) make devnet-clean. To view logs, run make devnet-logs

    "},{"location":"bnb-opbnb/advanced/local-dev-env/#notes","title":"Notes","text":"
    1. When executing for the first time, please be patient if you see the message \u201cWaiting for RPC server at\u2026\u201d, as the BSC network takes time to initialize.
    2. If you encounter an error during the \u201cDeploying contracts\u201d step, please try again as it usually recovers.
    "},{"location":"bnb-opbnb/advanced/local-dev-env/#additional-information","title":"Additional Information","text":"

    L1 chain ID is 714. L2 chain ID is 901.

    L1 test account:

    L2 test account:

    "},{"location":"bnb-opbnb/advanced/local-node/","title":"Run a Local Node - opBNB","text":""},{"location":"bnb-opbnb/advanced/local-node/#running-a-local-testnet-or-mainnet-node","title":"Running a Local Testnet or Mainnet Node","text":"

    If you\u2019re looking to build an app on opBNB you\u2019ll need access to an opBNB node. You can simply use the public rpc(Testnet: https://opbnb-testnet-rpc.bnbchain.org, Mainnet: https://opbnb-mainnet-rpc.bnbchain.org) or run your own node.

    This guide will walk you through setting up your own Testnet/Mainnet node.

    "},{"location":"bnb-opbnb/advanced/local-node/#hardware-requirements","title":"Hardware requirements","text":"

    Replicas must store the transaction history of opBNB and run Geth. For optimal performance, they should be powerful machines (real or virtual) with at least 16 GB RAM and an SSD drive with 500 GB free space (for production network).

    "},{"location":"bnb-opbnb/advanced/local-node/#fast-node","title":"Fast Node","text":"

    For users that just to run normal rpc node without debug functions, you can run the fast node which has faster sync speed and less hardware requirements.

    The fast node don\u2019t have MPT states and only use the snapshot to sync the latest state. The security is not as good as the full node, but it\u2019s enough for most of the users and validated in many production nodes. The advantage of the fast node is that it\u2019s faster to sync for it doesn\u2019t need to calculate the MPT states and store and query the MPT trees.

    You can start the fast node with the flags --allow-insecure-no-tries. The gc mode should not be archive if you start with the fast node.

    For more information, you can refer to the fast node pr.

    "},{"location":"bnb-opbnb/advanced/local-node/#run-with-docker","title":"Run with Docker","text":"

    There are official Docker images available for the opBNB node. You can use the latest versions of these images from the following links: - op-node - op-geth

    Additionally, you can find a docker-compose file example in this repository to run the opBNB node with Docker. This allows you to set up a Testnet/Mainnet node quickly, within minutes. If you use different infrastructure providers, please consult the docker-compose file and adjust the configuration as needed.

    "},{"location":"bnb-opbnb/advanced/local-node/#run-with-binaries","title":"Run with Binaries","text":""},{"location":"bnb-opbnb/advanced/local-node/#build-op-node-and-op-geth","title":"Build op-node and op-geth","text":"

    dependencies - golang 1.20+ - make - git - gcc - libc-dev

    You can refer to the Docker files for Alpine Linux: op-node and op-geth. If you are using a different OS, please find the alternative packages for your OS.

    export OPBNB_WORKSPACE=/tmp/opbnb\nmkdir -p $OPBNB_WORKSPACE\n\ncd $OPBNB_WORKSPACE\ngit clone https://github.com/bnb-chain/opbnb.git\ncd opbnb/op-node\ngit checkout develop\nmake op-node\nmkdir -p $OPBNB_WORKSPACE/op-node-data\ncp ./bin/op-node $OPBNB_WORKSPACE/op-node-data\n\ncd $OPBNB_WORKSPACE\ngit clone https://github.com/bnb-chain/op-geth.git\ncd op-geth\ngit checkout develop\nmake geth\nmkdir -p $OPBNB_WORKSPACE/op-geth-data\ncp ./build/bin/geth $OPBNB_WORKSPACE/op-geth-data/op-geth\n
    "},{"location":"bnb-opbnb/advanced/local-node/#data-preparation","title":"Data Preparation","text":"
    cd $OPBNB_WORKSPACE\n# for testnet\ncp $OPBNB_WORKSPACE/opbnb/assets/testnet/genesis.json $OPBNB_WORKSPACE/op-geth-data\n# for mainnet\n# cp $OPBNB_WORKSPACE/opbnb/assets/mainnet/genesis.json $OPBNB_WORKSPACE/op-geth-data\n\nopenssl rand -hex 32 > jwt.txt\ncp jwt.txt $OPBNB_WORKSPACE/op-geth-data\ncp jwt.txt $OPBNB_WORKSPACE/op-node-data\n\n# init op-geth genesis\ncd $OPBNB_WORKSPACE/op-geth-data\nmkdir datadir\n./op-geth --datadir ./datadir init genesis.json\n
    "},{"location":"bnb-opbnb/advanced/local-node/#start-components","title":"Start components","text":"

    op-geth

    #! /usr/bin/bash\ncd $OPBNB_WORKSPACE/op-geth-data\n\n# for testnet\nexport CHAIN_ID=5611\nexport L2_RPC=https://opbnb-testnet-rpc.bnbchain.org\nexport P2P_BOOTNODES=\"enr:-KO4QKFOBDW--pF4pFwv3Al_jiLOITj_Y5mr1Ajyy2yxHpFtNcBfkZEkvWUxAKXQjWALZEFxYHooU88JClyzA00e8YeGAYtBOOZig2V0aMfGhE0ZYGqAgmlkgnY0gmlwhDREiqaJc2VjcDI1NmsxoQM8pC_6wwTr5N2Q-yXQ1KGKsgz9i9EPLk8Ata65pUyYG4RzbmFwwIN0Y3CCdl-DdWRwgnZf,enr:-KO4QFJc0KR09ye818GT2kyN9y6BAGjhz77sYimxn85jJf2hOrNqg4X0b0EsS-_ssdkzVpavqh6oMX7W5Y81xMRuEayGAYtBSiK9g2V0aMfGhE0ZYGqAgmlkgnY0gmlwhANzx96Jc2VjcDI1NmsxoQPwA1XHfWGd4umIt7j3Fc7hKq_35izIWT_9yiN_tX8lR4RzbmFwwIN0Y3CCdl-DdWRwgnZf\"\n\n# for mainnet\n# export CHAIN_ID=204\n# export L2_RPC=https://opbnb-mainnet-rpc.bnbchain.org\n# export P2P_BOOTNODES=\"enr:-KO4QHs5qh_kPFcjMgqkuN9dbxXT4C5Cjad4SAheaUxveCbJQ3XdeMMDHeHilHyqisyYQAByfdhzyKAdUp2SvyzWeBqGAYvRDf80g2V0aMfGhHFtSjqAgmlkgnY0gmlwhDaykUmJc2VjcDI1NmsxoQJUevTL3hJwj21IT2GC6VaNqVQEsJFPtNtO-ld5QTNCfIRzbmFwwIN0Y3CCdl-DdWRwgnZf,enr:-KO4QKIByq-YMjs6IL2YCNZEmlo3dKWNOy4B6sdqE3gjOrXeKdNbwZZGK_JzT1epqCFs3mujjg2vO1lrZLzLy4Rl7PyGAYvRA8bEg2V0aMfGhHFtSjqAgmlkgnY0gmlwhDbjSM6Jc2VjcDI1NmsxoQNQhJ5pqCPnTbK92gEc2F98y-u1OgZVAI1Msx-UiHezY4RzbmFwwIN0Y3CCdl-DdWRwgnZf\"\n\n\n./op-geth \\\n  --datadir=\"./datadir\" \\\n  --verbosity=3 \\\n  --http \\\n  --http.corsdomain=\"*\" \\\n  --http.vhosts=\"*\" \\\n  --http.addr=0.0.0.0 \\\n  --http.port=8545 \\\n  --http.api=net,eth,engine \\\n  --ws \\\n  --ws.addr=0.0.0.0 \\\n  --ws.port=8545 \\\n  --ws.origins=\"*\" \\\n  --ws.api=eth,engine \\\n  --syncmode=full \\\n  --maxpeers=10 \\\n  --networkid=$CHAIN_ID \\\n  --miner.gaslimit=150000000 \\\n  --triesInMemory=32 \\\n  --txpool.globalslots=10000 \\\n  --txpool.globalqueue=5000 \\\n  --txpool.accountqueue=200 \\\n  --txpool.accountslots=200 \\\n  --cache 32000 \\\n  --cache.preimages \\\n  --allow-insecure-unlock \\\n  --authrpc.addr=\"0.0.0.0\" \\\n  --authrpc.port=\"8551\" \\\n  --authrpc.vhosts=\"*\" \\\n  --authrpc.jwtsecret=./jwt.txt \\\n  --gcmode=archive \\\n  --metrics \\\n  --metrics.port 6060 \\\n  --metrics.addr 0.0.0.0 \\\n  --rollup.sequencerhttp=$L2_RPC \\\n  --bootnodes=$P2P_BOOTNODES\n

    op-geth runs with PBSS(Path-Base Scheme Storage) and PebbleDB by adding the flags --state.scheme path and --db.engine pebble. It\u2019s recommended to start a new node with this mode, which provides better performance and less disk space usage.

    To start the op-geth node for a fast node, you can add the flag --allow-insecure-no-tries. but the gcmode should be full.

    op-node

    #! /usr/bin/bash\n\nset -ex\n\ncd op-node-data\n\nexport L2_RPC=http://localhost:8551\n# replace the p2p private key with yours\n# you can generate a new one with `openssl rand -hex 32`\nexport P2P_PRIV_KEY=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# for testnet\n# it's better to replace the L1_RPC with your own BSC Testnet RPC Endpoint for stability\nexport L1_RPC=https://bsc-testnet.bnbchain.org\nexport P2P_BOOTNODES=\"enr:-J24QGQBeMsXOaCCaLWtNFSfb2Gv50DjGOKToH2HUTAIn9yXImowlRoMDNuPNhSBZNQGCCE8eAl5O3dsONuuQp5Qix2GAYjB7KHSgmlkgnY0gmlwhDREiqaHb3BzdGFja4PrKwCJc2VjcDI1NmsxoQL4I9wpEVDcUb8bLWu6V8iPoN5w8E8q-GrS5WUCygYUQ4N0Y3CCIyuDdWRwgiMr,enr:-J24QJKXHEkIhy0tmIk2EscMZ2aRrivNsZf_YhgIU51g4ZKHWY0BxW6VedRJ1jxmneW9v7JjldPOPpLkaNSo6cXGFxqGAYpK96oCgmlkgnY0gmlwhANzx96Hb3BzdGFja4PrKwCJc2VjcDI1NmsxoQMOCzUFffz04eyDrmkbaSCrMEvLvn5O4RZaZ5k1GV4wa4N0Y3CCIyuDdWRwgiMr\"\n\n# for mainnet\n# export L1_RPC=https://bsc-dataseed.bnbchain.org\n# export P2P_BOOTNODES=\"enr:-J24QA9sgVxbZ0KoJ7-1gx_szfc7Oexzz7xL2iHS7VMHGj2QQaLc_IQZmFthywENgJWXbApj7tw7BiouKDOZD4noWEWGAYppffmvgmlkgnY0gmlwhDbjSM6Hb3BzdGFja4PMAQCJc2VjcDI1NmsxoQKetGQX7sXd4u8hZr6uayTZgHRDvGm36YaryqZkgnidS4N0Y3CCIyuDdWRwgiMs,enr:-J24QPSZMaGw3NhO6Ll25cawknKcOFLPjUnpy72HCkwqaHBKaaR9ylr-ejx20INZ69BLLj334aEqjNHKJeWhiAdVcn-GAYv28FmZgmlkgnY0gmlwhDTDWQOHb3BzdGFja4PMAQCJc2VjcDI1NmsxoQJ-_5GZKjs7jaB4TILdgC8EwnwyL3Qip89wmjnyjvDDwoN0Y3CCIyuDdWRwgiMs\"\n\n./op-node \\\n  --l1.trustrpc \\\n  --sequencer.l1-confs=15 \\\n  --verifier.l1-confs=15 \\\n  --l1.http-poll-interval 3s \\\n  --l1.epoch-poll-interval 45s \\\n  --l1.rpc-max-batch-size 20 \\\n  --rollup.config=./rollup.json \\\n  --rpc.addr=0.0.0.0 \\\n  --rpc.port=8546 \\\n  --p2p.sync.req-resp \\\n  --p2p.listen.ip=0.0.0.0 \\\n  --p2p.listen.tcp=9003 \\\n  --p2p.listen.udp=9003 \\\n  --snapshotlog.file=./snapshot.log \\\n  --p2p.bootnodes=$P2P_BOOTNODES \\\n  --metrics.enabled \\\n  --metrics.addr=0.0.0.0 \\\n  --metrics.port=7300 \\\n  --pprof.enabled \\\n  --rpc.enable-admin \\\n  --l1=${L1_RPC} \\\n  --l2=${L2_RPC} \\\n  --l2.jwt-secret=./jwt.txt \\\n  --l2.engine-sync=true \\\n  --l2.skip-sync-start-check=true \\  \n  --log.level=debug\n
    "},{"location":"bnb-opbnb/advanced/local-node/#run-with-snapshots","title":"Run with Snapshots","text":"

    To improve the synchronization speed of the node, you can utilize snapshots to initialize it.

    The most recent snapshot is maintained in the repository opbnb-snapshot. Please visit the repository for download links and usage instructions.

    "},{"location":"bnb-opbnb/advanced/local-node/#check-status","title":"Check status","text":"

    Wait for the node to sync. You\u2019ll see log in op-geth if there\u2019s any new block.

    INFO [11-15|10:10:05.569] Syncing beacon headers                   downloaded=1,762,304 left=11,403,991 eta=27m1.039s\nINFO [11-15|10:10:06.440] Forkchoice requested sync to new head    number=13,164,499 hash=d78cb3..a2e94d finalized=unknown\n

    You can check the block number with curl:

    $ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}' http://localhost:8545\n

    Once all headers have been downloaded, the node will begin downloading the blocks. You will notice that the block height is increasing.

    {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0x1a\"}\n

    To verify if the node has synchronized to the latest height, you can compare the block with the one requested from public endpoints.

    # local\n$ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"id\": 1, \"params\": [\"0x1a\", false]}' http://localhost:8545\n\n# testnet\n$ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"id\": 1, \"params\": [\"0x1a\", false]}' https://opbnb-testnet-rpc.bnbchain.org\n\n# mainnet\n$ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"id\": 1, \"params\": [\"0x1a\", false]}' https://opbnb-mainnet-rpc.bnbchain.org\n
    "},{"location":"bnb-opbnb/advanced/local-node/#troubleshooting","title":"Troubleshooting","text":"

    If the problem you are facing is not addressed here, please open an issue on GitHub by visiting this link: open an issue.

    "},{"location":"bnb-opbnb/advanced/local-node/#not-synced-for-a-long-time","title":"Not synced for a long time","text":"

    The default sync mechanism involves two P2P networks, the op-node network and op-geth network. If you are not connected to the op-node network, you can not receive the latest blocks from broadcast, and can\u2019t trigger the engine sync of op-geth. If you are not connected to the op-geth network, you can receive the latest blocks from broadcast, but can\u2019t get the historical blocks from op-geth P2P network.

    Check the op-geth logs.

    If you can find the following logs, it means that the op-node network is connected successfully and you are receiving the latest blocks from broadcast.

    INFO [11-15|10:32:02.801] Forkchoice requested sync to new head    number=8,290,596 hash=1dbff3..9a306a finalized=unknown\n

    If you can find the following logs, it means that the op-geth network is connected successfully and you are receiving the historical block headers from op-geth P2P network.

    INFO [11-15|10:32:52.240] Syncing beacon headers                   downloaded=210,432 left=8,084,773 eta=31m39.748s\n

    Check the op-node p2p network with the command below:

    $ curl -X POST -H \"Content-Type: application/json\" --data \\\n    '{\"method\":\"opp2p_peers\",\"params\":[true],\"id\":1,\"jsonrpc\":\"2.0\"}'  \\\n    http://localhost:8546\n

    Check the op-geth p2p network with the command below. You have to enable admin API in op-geth to use this API. Refer to https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-admin for more details.

    $ curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"admin_peers\",\"params\":[],\"id\":1}' http://localhost:8545 | jq .\n
    "},{"location":"bnb-opbnb/advanced/local-node/#the-local-nodes-chain-has-forked-from-the-canonical-chain","title":"The local node\u2019s chain has forked from the canonical chain","text":"

    If your local node is already running and tracking blocks, the following situations may indicate that your local node\u2019s chain has forked from the canonical chain: 1. The block hash at the same height obtained through the eth_getBlockByNumber method does not match the data returned by the public node. 2. Your local chain consistently lags behind a fixed number of blocks and cannot catch up with the latest block height.

    In this case, we recommend that you check the code version of the running node through the following steps:

    $ op-node -v\nop-node version v0.0.0-515ebd51-1698742099\n\n$ op-geth version\nGeth\nVersion: 0.1.0-unstable\nGit Commit: f8871fc80dbf2aa0178b504e76c20c21b890c6d5\nGit Commit Date: 20231026\nUpstream Version: 1.11.5-stable\nArchitecture: arm64\nGo Version: go1.20.2\nOperating System: darwin\nGOPATH=\n
    Please make sure to use the latest code version. If the code version is incorrect, please completely clear the node data and run the new node again according to this guide.

    You also need to check if the genesis.json and rollup.json files are up to date.

    In the latest code, we hardcoded the configuration of rollup.json. Instead of using --rollup.config=./rollup.json, you just need to use --network=opBNBTestnet (for the mainnet network it is opBNBMainnet). This change ensures that the contents of rollup.json will not be incorrect.

    "},{"location":"bnb-opbnb/advanced/local-node/#node-block-is-stuck-and-op-geth-log-prints-database-compacting-degraded-performance-databasedatagethchaindata","title":"Node block is stuck and op-geth log prints: Database compacting, degraded performance database=/data/geth/chaindata","text":"

    If your node suddenly gets stuck and cannot grow, and your op-geth log keeps printing: Database compacting, degraded performance database=/data/geth/chaindata, then you need to consider upgrading your machine specifications, increasing CPU, memory, and disk maximum throughput.

    This is because the current OP Stack only supports the archive mode of Geth, and the disk space usage increases over time. The Leveldb that Geth relies on requires more machine resources to complete the compact process. We are working hard to support full mode Geth, and further support PBSS and Pebble to completely solve this problem.

    If you don\u2019t want to upgrade your machine\u2019s specifications, You can choose to download the pruned snapshot from the opbnb-snapshot repository, and use it to start a new node. The new node will not have this issue, but it will lose all state data before a certain block height.

    If you are an advanced player, you can also try to perform offline pruning on your nodes (Note that this is a dangerous operation and after pruning, the state data of the blocks before the target block height will no longer be available). You can follow these steps: 1. Shut down your machine and make sure that op-geth prints the following log: \u201cBlockchain stopped\u201d. 2. Search for the keyword \u201cChain head was updated\u201d in the logs to confirm the block height of the last inserted block before the node was shut down. For the sake of explanation, let\u2019s assume the block height is 16667495. 3. Wait for 16667495 to become the final state on the chain, ensuring that no reorganization has occurred. You can go to the blockchain explorer (https://opbnbscan.com/) to query this block height, and compare the block height hash with the one in the log. If the hashes match and a long time has passed, then we believe that this block height will not be reorganized. 4. Get the state root hash of this block height through JSON-RPC. 5. To execute pruning, use the following command: geth snapshot prune-state --datadir {yourDataDir} --triesInMemory=32 {targetBlockStateRootHash}, making sure to replace {yourDataDir} and {targetBlockStateRootHash} with your own values. 6. Be patient and observe the logs. The entire process may take dozens of hours. 7. Restart your node after pruning is complete.

    Info

    Pruning is very dangerous and may damage the data of the node. This could result in having to rerun the new node. Please only perform this operation if you are familiar with the process.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/","title":"Best Practices - opBNB Node Configuration","text":""},{"location":"bnb-opbnb/advanced/node-best-practices/#best-practices-for-opbnb-node-configuration","title":"Best Practices for opBNB Node Configuration","text":""},{"location":"bnb-opbnb/advanced/node-best-practices/#selecting-the-appropriate-mode-and-storage-scheme","title":"Selecting the Appropriate Mode and Storage Scheme","text":"

    opBNB accommodates various node modes: Full, Fast, and Archive. Two storage schemes are available: HBSS (Hash-Based Scheme Storage) and PBSS (Path-Based Scheme Storage).

    The principal distinctions between them lie in their methods of preserving history trie data.

    The Merkle Patricia Trie (MPT), an advanced data structure, is adept at storing and retrieving key-value pairs with efficiency. It amalgamates the principles of a Patricia trie and a Merkle tree to forge a secure and immutable representation of data within the Ethereum Virtual Machine (EVM).

    The MPT endows the following capabilities:

    Nevertheless, the preservation of entire history trie data on disk can demand substantial resources and may be superfluous for certain applications. opBNB introduces diverse node modes and storage schemes to accommodate a range of requirements.

    The variances between the modes and storage schemes are encapsulated as follows:

    Comparative Analysis of Node Modes and Storage Schemes:

    Mode Full Node (PBSS) Full Node (HBSS) Fast Node Archive Node Preserve Trie Nodes Latest 128 blocks Latest 128 blocks None All Disk Consumption Moderate-Low Moderate-High Lowest Highest Auto Prune History Trie Data Yes No Not Applicable Not Applicable Performance Moderate-High Moderate-Low Highest Lowest Security High High Lower than others since it doesn\u2019t verify the state root High"},{"location":"bnb-opbnb/advanced/node-best-practices/#fast-node","title":"Fast Node","text":"

    For most applications, operating a fast node is advisable. This mode maintains only the current state, sans trie data, making it suitable for tasks such as querying the current state and processing transactions.

    To activate the fast node, include --allow-insecure-no-tries in the op-geth startup command.

     ./geth --config ./config.toml --datadir ./node --syncmode full  --allow-insecure-no-tries\n

    To prune the MPT state (e.g., when transitioning from a full to a fast node), prune the node as follows:

    ./geth snapshot insecure-prune-all --datadir ./datadir ./genesis.json\n

    Fast Node does not generate Trie Data when syncing. Once the Fast Node is running, there is no way to switch back to Full Node. Need to re-download snapshot data to restore it to Full Node.

    For implementation details and further information, refer to the PR.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#full-node","title":"Full Node","text":"

    Operating a full node is recommended if you require:

    To enable the full node, set the --syncmode full flag in the geth command.

    It is particularly advised to operate a full node with PBSS and pebble to minimize data redundancy and enhance performance.

    --state.scheme path --db.engine pebble\n

    For comprehensive details, consult the PBSS document.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#archive-nodewith-op-reth","title":"Archive Node(with op-reth)","text":"

    The Archive node mode archives the entirety of history trie data. This mode is apt for scenarios necessitating access to the complete history trie data, such as block explorers and analytics.

    The current volume of history trie data approximates 3TB (as of the end of April, 2024). Significant performance issues may arise in the op-geth implementation when managing extensive history trie data. Therefore, it is recommended to operate the archive node in conjunction with op-reth.

    You can refer to Reth Node for opBNB for additional details.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#snapshots","title":"Snapshots","text":"

    The latest snapshot data is accessible via the opbnb-snapshot repository.

    Employing snapshot data can drastically curtail the time required for node synchronization.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#performance-optimization","title":"Performance Optimization","text":"

    In order to enhance the performance of op-geth, it is crucial to configure the cache settings appropriately. Allocating approximately one-third of the physical memory to the cache is advisable. For instance, if the system has 64GB of physical memory, the cache setting can be configured as:

    --cache 20000\n

    This allocation ensures that the cache is optimized for efficient use of system resources, ultimately leading to improved performance of op-geth.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#running-server-as-a-daemon","title":"Running Server as a Daemon","text":"

    To ensure continuous operation, it is important to keep op-node and op-geth running at all times. One of the simplest and recommended solutions is to register them as systemd service. By doing so, they will automatically start upon system reboots and other relevant events, ensuring seamless operation without manual intervention.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#security","title":"Security","text":""},{"location":"bnb-opbnb/advanced/node-best-practices/#securing-your-full-node-rpc-from-hackers","title":"Securing Your Full Node RPC from Hackers","text":"

    It is imperative to safeguard your Full Node RPC endpoints from unauthorized access. Exposing RPC endpoints to the public network can pose security risks, making it essential to restrict access and implement appropriate security measures to prevent unauthorized intrusion.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#software-vulnerabilities","title":"Software Vulnerabilities","text":"

    To ensure the security of your node and assets, it is crucial to download software only from official sources. Additionally, it is important to consistently update the software to the latest, most secure version available. By adhering to these practices, you can mitigate the risk of potential vulnerabilities and safeguard your node and assets from security threats.

    "},{"location":"bnb-opbnb/advanced/node-best-practices/#faq","title":"FAQ","text":""},{"location":"bnb-opbnb/advanced/node-best-practices/#why-does-my-node-experience-offline-status-or-block-height-lag-after-an-abrupt-termination","title":"Why does my node experience offline status or block height lag after an abrupt termination?","text":"

    After running a synchronized node for an extended period of time, abruptly terminating the node(op-geth process) can result in a period of offline status upon restart. Specifically, only archived nodes are expected to quickly re-synchronize after such an event.

    The reason for this behavior lies in the nature of Geth\u2019s functionality. When Geth experiences a crash or is not shut down gracefully, the recent state that was held in memory is lost and must be regenerated. As a result, it can take Geth a considerable amount of time to restore these states.

    The root cause of this prolonged restoration process can be attributed to the fact that Geth does flush the state trie periodically. The frequency of this flushing is defined by the trieTimeout parameter in the configuration file (config.toml). This periodic flushing is intended to maintain consistency and integrity within the node\u2019s state, but it also contributes to the time required for state regeneration in the event of an abrupt shutdown.

    "},{"location":"bnb-opbnb/advanced/reth-node/","title":"Reth Node - opBNB Develop","text":""},{"location":"bnb-opbnb/advanced/reth-node/#reth-node-for-opbnb","title":"Reth Node for opBNB","text":"

    OpBNB Reth is a Rust client developed to provide support for the opBNB network. It aims to enhance client diversity and performance on the BNB Chain.

    "},{"location":"bnb-opbnb/advanced/reth-node/#hardware-specifications","title":"Hardware Specifications","text":"

    To run OpBNB Reth effectively, ensure your system meets the following hardware requirements:

    "},{"location":"bnb-opbnb/advanced/reth-node/#running-opbnb-reth-node","title":"Running opBNB Reth Node","text":"

    The opBNB Reth is an execution client for opBNB network. You need to run op-node along with op-reth to synchronize with the opBNB network.

    It\u2019s important to note that both op-node and op-reth must use the same JWT secret file for authentication. You can use the following command to generate JWT secret file and copy to the workdir for running op-node and op-reth.

    openssl rand -hex 32 > jwt.txt\n
    "},{"location":"bnb-opbnb/advanced/reth-node/#running-op-node","title":"Running OP Node","text":"
    1. Download source code and build

      git clone https://github.com/bnb-chain/opbnb\ncd opbnb\nmake op-node\n
    2. Start op-node

      # for mainnet\nexport network=mainnet\nexport L1_RPC=https://bsc-dataseed.bnbchain.org\nexport P2P_BOOTNODES=\"enr:-J24QA9sgVxbZ0KoJ7-1gx_szfc7Oexzz7xL2iHS7VMHGj2QQaLc_IQZmFthywENgJWXbApj7tw7BiouKDOZD4noWEWGAYppffmvgmlkgnY0gmlwhDbjSM6Hb3BzdGFja4PMAQCJc2VjcDI1NmsxoQKetGQX7sXd4u8hZr6uayTZgHRDvGm36YaryqZkgnidS4N0Y3CCIyuDdWRwgiMs,enr:-J24QPSZMaGw3NhO6Ll25cawknKcOFLPjUnpy72HCkwqaHBKaaR9ylr-ejx20INZ69BLLj334aEqjNHKJeWhiAdVcn-GAYv28FmZgmlkgnY0gmlwhDTDWQOHb3BzdGFja4PMAQCJc2VjcDI1NmsxoQJ-_5GZKjs7jaB4TILdgC8EwnwyL3Qip89wmjnyjvDDwoN0Y3CCIyuDdWRwgiMs\"\n\n# for testnet\n# it's better to replace the L1_RPC with your own BSC Testnet RPC Endpoint for stability\n# export network=testnet\n# export L1_RPC=https://bsc-testnet.bnbchain.org\n# export P2P_BOOTNODES=\"enr:-J24QGQBeMsXOaCCaLWtNFSfb2Gv50DjGOKToH2HUTAIn9yXImowlRoMDNuPNhSBZNQGCCE8eAl5O3dsONuuQp5Qix2GAYjB7KHSgmlkgnY0gmlwhDREiqaHb3BzdGFja4PrKwCJc2VjcDI1NmsxoQL4I9wpEVDcUb8bLWu6V8iPoN5w8E8q-GrS5WUCygYUQ4N0Y3CCIyuDdWRwgiMr,enr:-J24QJKXHEkIhy0tmIk2EscMZ2aRrivNsZf_YhgIU51g4ZKHWY0BxW6VedRJ1jxmneW9v7JjldPOPpLkaNSo6cXGFxqGAYpK96oCgmlkgnY0gmlwhANzx96Hb3BzdGFja4PrKwCJc2VjcDI1NmsxoQMOCzUFffz04eyDrmkbaSCrMEvLvn5O4RZaZ5k1GV4wa4N0Y3CCIyuDdWRwgiMr\"\n\n./op-node/bin/op-node \\\n  --l1.trustrpc \\\n  --sequencer.l1-confs=15 \\\n  --verifier.l1-confs=15 \\\n  --l1.http-poll-interval 60s \\\n  --l1.epoch-poll-interval 180s \\\n  --l1.rpc-max-batch-size 20 \\\n  --rollup.config=./assets/${network}/rollup.json \\\n  --rpc.addr=0.0.0.0 \\\n  --rpc.port=8546 \\\n  --p2p.sync.req-resp \\\n  --p2p.listen.ip=0.0.0.0 \\\n  --p2p.listen.tcp=9003 \\\n  --p2p.listen.udp=9003 \\\n  --snapshotlog.file=./snapshot.log \\\n  --p2p.bootnodes=$P2P_BOOTNODES \\\n  --metrics.enabled \\\n  --metrics.addr=0.0.0.0 \\\n  --metrics.port=7300 \\\n  --pprof.enabled \\\n  --rpc.enable-admin \\\n  --l1=${L1_RPC} \\\n  --l2=http://localhost:8551 \\\n  --l2.jwt-secret=./jwt.txt \\\n  --syncmode=execution-layer\n
    "},{"location":"bnb-opbnb/advanced/reth-node/#running-opbnb-reth-archive-node","title":"Running opBNB Reth Archive Node","text":"
    1. Download source code and build

      git clone https://github.com/bnb-chain/reth.git\ncd reth\nmake build-op\n
    2. Start op-reth

      # for mainnet\nexport network=mainnet\nexport L2_RPC=https://opbnb-mainnet-rpc.bnbchain.org\n\n# for testnet\n# export network=testnet\n# export L2_RPC=https://opbnb-testnet-rpc.bnbchain.org\n\n./target/release/op-reth node \\\n    --datadir=./datadir \\\n    --chain=opbnb-${network} \\\n    --rollup.sequencer-http=${L2_RPC} \\\n    --authrpc.addr=\"0.0.0.0\" \\\n    --authrpc.port=8551 \\\n    --authrpc.jwtsecret=./jwt.txt \\\n    --http \\\n    --http.api=\"eth, net, txpool, web3, rpc\" \\\n    --log.file.directory ./datadir/logs\n
    3. Alternatively, you can run the op-reth node with docker

      # for mainnet\nexport network=mainnet\nexport L2_RPC=https://opbnb-mainnet-rpc.bnbchain.org\n\n# for testnet\n# export network=testnet\n# export L2_RPC=https://opbnb-testnet-rpc.bnbchain.org\n\n# check this for version of the docker image, https://github.com/bnb-chain/reth/pkgs/container/op-reth\nexport version=latest\n\n# the directory where reth data will be stored\nexport data_dir=/xxx/xxx\n\n# the directory where the jwt.txt file is stored\nexport jwt_dir=/xxx/xxx\n\ndocker run -d -p 8545:8545 -p 30303:30303 -p 30303:30303/udp -v ${data_dir}:/data -v ${jwt_dir}:/jwt \\\n    --name op-reth ghcr.io/bnb-chain/op-reth:${version} node \\\n    --datadir=/data \\\n    --chain=opbnb-${network} \\\n    --rollup.sequencer-http=${L2_RPC} \\\n    --authrpc.addr=\"0.0.0.0\" \\\n    --authrpc.port=8551 \\\n    --authrpc.jwtsecret=/jwt/jwt.txt \\\n    --http \\\n    --http.api=\"eth, net, txpool, web3, rpc\" \\\n    --log.file.directory /data/logs\n
    "},{"location":"bnb-opbnb/advanced/reth-node/#running-opbnb-reth-full-node","title":"Running opBNB Reth Full Node","text":"

    To run a full node, simply add the --full flag when starting the op-reth node.

    "},{"location":"bnb-opbnb/advanced/reth-node/#benchmark-results","title":"Benchmark Results","text":"

    We benchmark Reth(v1.0.0), op-nodes(v0.4.2) on AWS i4g.4xlarge(16 core 128G) instance with NVMe SSD for opBNB. It may take approximately 53 hours to sync the latest block on opBNB mainnet for an archive node and 50 hours for a full node.

    The op-reth supports Stage Sync which is rearchitected for better performance for the initial sync from genesis and Live Sync. The following table displays the total time to stage sync and storage distribution after catch up on opBNB network:

    The result shows an encouraging 690 MGas/s result on historical sync in the last 1M blocks (the historical sync numbers represent pure execution time during \u201cbackfills\u201d).

    The live sync performance on the opBNB network is not very optimistic. We conducted an observation of the metrics for blocks [30467068, 30429919].

    The main reason for the underperformance of Live sync is that mdbx is not a write-friendly database. The commit db at the end of block execution takes up several tens of milliseconds, a challenge that becomes more pronounced for fast-blocking layer 2 solutions like opBNB.

    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/","title":"Run op-geth with PBSS and PebbleDB - opBNB","text":""},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#how-to-run-op-geth-with-pbss-and-pebbledb","title":"How to Run op-geth with PBSS and PebbleDB","text":"

    To start op-geth with PBSS and PebbleDB, include the following flags:

    --state.scheme path --db.engine pebble\n

    Info

    We recommend using version v0.3.1-alpha or later to activate this feature.

    Upon successful startup, the logs will confirm the initiation of PBSS and PebbleDB:

    INFO [03-21|07:00:25.684] Using pebble as the backing database\nINFO [03-21|07:00:47.039] State scheme set by user                 scheme=path\n
    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#pbss-path-based-scheme-storage","title":"PBSS (Path-Based Scheme Storage)","text":"

    PBSS stores trie nodes on disk using the encoded path and a specific key prefix as the key. This approach allows PBSS\u2019s Merkle Patricia Trie (MPT) to overwrite older data due to the shared key between the account trie and storage trie. This feature not only enables online pruning but also significantly reduces data redundancy.

    PBSS architecture comprises 128 difflayers (in memory) and one disk layer, as depicted below. Difflayers store only the state data changes.

    +-------------------------------------------+\n| Block X+128 State                         |\n+-------------------------------------------+\n| Block X+127 State                         |\n+-------------------------------------------+\n|              .......                      |\n+-------------------------------------------+\n| Block X+1 State, Bottom-most diff layer   |\n+-------------------------------------------+\n| Block X State, Disk layer (singleton trie)|\n+-------------------------------------------+\n

    PBSS offers superior read performance, with faster trie access and iteration. It maintains a single version of the state trie on disk and keeps new tries (changes to the state/storage/account trie) only in memory.

    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#restrictions","title":"Restrictions","text":"

    RPC requests requiring data beyond this range will return an error: missing trie node ${hash} (path ${path}). Only RPC methods that need to query trie data, such as eth_getProof, will be impacted by this limitation, while others will remain unaffected.

    This function might require querying state data from an hour earlier to obtain a withdrawal proof, which is not supported yet. Future versions will address this limitation.

    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#pebbledb","title":"PebbleDB","text":"

    PebbleDB, now the default database for the community, has been integrated into go-ethereum. It replaces LevelDB, which lacks a throttle mechanism for flushes and compactions, leading to latency spikes during intense read and write operations.

    Conversely, PebbleDB features separate rate limiters for flushes and compactions, conducting operations as needed and reducing unnecessary disk bandwidth consumption.

    "},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#faq","title":"FAQ","text":""},{"location":"bnb-opbnb/advanced/run-with-pebbledb-and-pbss/#can-i-change-the-statescheme-or-dbengine-for-an-existing-node","title":"Can I change the state.scheme or db.engine for an existing node?","text":"

    No, you cannot change the state.scheme or db.engine for an existing node. You must start a new node with the desired configuration.

    "},{"location":"bnb-opbnb/advanced/verify-on-opbnbscan/","title":"Verify on opbnbscan - opBNB","text":""},{"location":"bnb-opbnb/advanced/verify-on-opbnbscan/#use-opbnbscan-to-verify-your-contract-via-hardhat-and-truffle","title":"Use opBNBScan to verify your contract via Hardhat and Truffle","text":"

    opBNBScan provides a convenient and user-friendly platform for developers to verify their smart contracts using popular developer tools like Truffle and Hardhat. Here are the step-by-step instructions to get started with opBNBScan\u2019s smart contract verification APIs.

    1. Go to the NodeReal portal and click the Login button.
    2. Login with your github account or discord account.
    3. And create your API key by clicking the create new key button.
    4. Copy your API key to your clipboard and and use it as your key of smart verification contract APIs.
    "},{"location":"bnb-opbnb/advanced/verify-on-opbnbscan/#hardhat","title":"Hardhat","text":"

    You can use the hardhat-verify plugin to verify your deployed smart contract. You can follow the steps in the hardhat document. Below is an example of how to configure your hardhat.config.js. Pay attention to the network\u2019s configuration settings, and replace the corresponding settings that meet your requirements.

    require(\"@nomicfoundation/hardhat-toolbox\");\nrequire(\"@nomicfoundation/hardhat-verify\");\n/** @type import('hardhat/config').HardhatUserConfig */\n\nmodule.exports = {\n  solidity: \"0.8.19\", //replace your own solidity compiler version\n  networks: {\n    opbnb: {\n      url: \"https://opbnb-testnet-rpc.bnbchain.org/\",\n      chainId: 5611, // Replace with the correct chainId for the \"opbnb\" network\n      accounts: [\"{{YOUR-PRIVATE-KEY}}\"], // Add private keys or mnemonics of accounts to use\n      gasPrice: 20000000000,\n    },\n  },\n  etherscan: {\n    apiKey: {\n      opbnb: \"{{YOUR-NODEREAL-API-KEY}}\", //replace your nodereal API key\n    },\n\n    customChains: [\n      {\n        network: \"opbnb\",\n        chainId: 5611, // Replace with the correct chainId for the \"opbnb\" network\n        urls: {\n          apiURL:\n            \"https://open-platform.nodereal.io/{{YOUR-NODEREAL-API-KEY}}/op-bnb-testnet/contract/\",\n          browserURL: \"https://testnet.opbnbscan.com/\",\n        },\n      },\n    ],\n  },\n};\n
    "},{"location":"bnb-opbnb/advanced/verify-on-opbnbscan/#truffle","title":"Truffle","text":"

    You can also use truffle to verify your smart contract on opBNBScan.

    Please make sure the truffle-plugin-verify is installed correctly, and in the plugin, add the \u2018truffle-plugin-verify\u2019

    module.exports = {\n plugins: [\n  'truffle-plugin-verify'\n ],\n networks:\n {\n  development: {\n    host: \"127.0.0.1\", // Localhost (default: none)\n    port: 8545, // Standard port (default: none)\n    network_id: \"*\", // Any network (default: none)\n    },\n    dashboard: {\n    verify: {\n    apiUrl: 'https://open-platform.nodereal.io/{{YOUR-NODEREAL-API-KEY}}/op-bnb-testnet/contract/',\n    apiKey: '{{YOUR-NODEREAL-API-KEY}}',\n    explorerUrl: 'https://testnet.opbnbscan.com/',\n        },\n            host: \"127.0.0.1\",\n            port: 24012,\n            network_id: \"*\"\n        },\n },\n// Set default mocha options here, use special reporters, etc.\nmocha: {\n// timeout: 100000\n},\n// Configure your compilers\ncompilers: {\n    solc: {\n        version: \"0.8.15\", // Fetch exact version from solc-bin (default: truffle's version)\n    }\n},\n

    Make sure your smart contract is deployed first. I am using the dashboard to avoid saving your private credentials to your local machine.

    npx truffle migrate \u2013network dashboard\n

    And then you can verify your smart contract by specifying your contract name

    npx truffle run verify {{Your-Contract-Name}} --network dashboard\n

    Then you can go to the opBNBScan explorer to check if your smart contract has been verified.

    Info

    For the mainnet contract verification, please change the following URLs: url: \u201chttps://opbnb-testnet-rpc.bnbchain.org/\u201d change to \u201chttps://opbnb-mainnet-rpc.bnbchain.org/\u201d apiUrl: \u2018https://open-platform.nodereal.io/{{YOUR-NODEREAL-API-KEY}}/op-bnb-testnet/contract/\u2019 change to \u2018https://open-platform.nodereal.io/{{YOUR-NODEREAL-API-KEY}}/op-bnb-mainnet/contract/\u2018

    "},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/","title":"Account Abstraction - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/#account-abstraction","title":"Account Abstraction","text":""},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/#opbnb-is-a-cost-efficient-solution-for-aa","title":"opBNB is a cost-efficient solution for AA","text":"

    The primary allure of opBNB lies in its ability to significantly reduce the gas costs associated with AA (ERC4337) transactions. This efficiency is achieved through optimized transaction processing and a more streamlined approach to handling complex operations typically found in AA transactions. AA transactions, with their intricate operations and smart contract interactions, traditionally require more computational resources. opBNB, however, utilizes innovative methods to simplify these processes, ensuring that the complexity does not translate into prohibitive costs for users and developers.

    "},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/#enhanced-transaction-speed-with-lower-costs","title":"Enhanced transaction speed with lower costs","text":"

    Not only does opBNB address the cost issue, but it also offers higher Transaction Per Second (TPS) rates. This combination of low cost and high speed is particularly crucial for dApps that require both efficiency and scalability, making opBNB a ideal choice for High-Frequency DeFi and web3 games. By integrating opBNB, dApp developers can offer their users a seamless experience without the burden of high transaction fees. This user-friendly approach, coupled with cost-effective operations, positions opBNB as a preferred choice in the AA landscape.

    "},{"location":"bnb-opbnb/core-concepts/account-abstraction-on-opbnb/#opbnb-aa-infrastructure","title":"opBNB AA Infrastructure","text":"

    Notably, platforms like Biconomy and Particle Wallet have already adopted opBNB\u2019s AA solutions. Their integration showcases the practical application and effectiveness of opBNB in managing the complexity and cost of AA transactions in real-world scenarios. For details, please refer to the blog of Account Abstraction current and future development on BNB Chain.

    "},{"location":"bnb-opbnb/core-concepts/gas-and-fees/","title":"Why OP Stack - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/gas-and-fees/#gas-and-fees","title":"Gas and Fees","text":"

    OpBNB is a Layer 2 scaling solution that aims to achieve higher throughput and lower cost for transactions on the BNB Smart Chain. The cost of opBNB transactions consists of two components: the Layer 2 gas fee and the Layer 1 gas fee. The Layer 2 gas fee reflects the computational complexity of the transaction. The Layer 1 gas fee covers the expense of submitting batches of transactions to the BSC for verification and finality.

    Gas price = base price + priority price

    Layer 2 transaction cost = Layer 2 gas price x Layer 2 gas consumed + Layer 1 gas price x Layer 1 gas consumed.

    "},{"location":"bnb-opbnb/core-concepts/gas-and-fees/#current-configuration","title":"Current configuration","text":"Name Floor Base Price Minimum Priority Price opBNB Testnet 8 wei (dynamic) 1001 wei opBNB Mainnet 8 wei (dynamic) 1001 wei BSC Testnet 0 3 BSC Mainnet 0 3"},{"location":"bnb-opbnb/core-concepts/gas-and-fees/#what-does-this-means","title":"What does this means","text":"

    Please note the floor base price is the minimum base price opBNB can set, and according to the usage, the base price can fluctuate. For example, according to the current configuration, if the usage of a block reaches 50% of 100M gas, the base price will increase by 12.5%.

    The minimum priority price is preconfigured, and users can give any priority price that is higher than this number. Usually users will get the estimate gas price by calling the API of \u201cestimate gas price\u201d. It is a recommended gas price according to the current average gas price of history blocks.

    BNB Chain aims to reduce the transaction cost to the level that enable the mass adoption, for opBNB, the target of the transfer transaction is lower than $0.001.

    "},{"location":"bnb-opbnb/core-concepts/gas-and-fees/#how-opbnb-keep-reducing-the-cost-of-l2-transactions","title":"How opBNB keep reducing the cost of L2 transactions","text":"
    1. Enhanced Data Compression: Implementing more advanced data compression algorithms to reduce the size of L2 transaction data before submitting it to L1.

    2. Efficient Transaction Batching: Optimizing how transactions are batched together to maximize space efficiency and reduce costs per transaction.

    3. Data Availability Solutions: Utilizing solutions like those in BNB Greenfield for offloading some data storage from the main chain, thereby reducing data costs.

    4. Zero-Knowledge Proofs: Employing zero-knowledge proofs to validate transactions without disclosing full transaction data, thus minimizing L1 data load.

    5. Protocol-Level Optimizations: Making improvements at the protocol level to reduce overhead in transaction processing on L2.

    "},{"location":"bnb-opbnb/core-concepts/opbnb-metrics/","title":"opBNB Metrics - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/opbnb-metrics/#opbnb-metrics","title":"opBNB Metrics","text":"

    Compared with other L2 solutions on the Ethereum, like OP Mainnet and Arbitrum, opBNB has lower gas fee, and higher block gas limit, which means the gas fee will be more stable when traffic of Layer 2 increases. I listed the Ethereum EIP-1559 parameters as a reference. Arbitrum gas mechanism is based on the ArbOS, it is not applicable here.

    Gas Parameter Differences

    Parameter opBNB value Optimism value Block gas limit 100,000,000 gas 30,000,000 gas Block gas target 50,000,000 gas 5,000,000 gas EIP-1559 elasticity multiplier 2 6 EIP-1559 denominator 8 50 Maximum base fee increase (per block) 12.5% 10% Maximum base fee decrease (per block) 12.5% 2%

    Metrics Differences

    opBNB Optimism Arbitrum Gas Token BNB ETH ETH VM EVM EVM EVM Gas Fee $0.001 $0.05 $0.1 Block Gas Limit 100M(150M 2024Q1) 30M 32M Block time 1s 2s 0.25s(Min) Withdraw/ Finality 7 days 7 days 7 days TPS (Transfer) 4500+ 700+ 4000+

    OP Stack has some minor differences, so does opBNB. I just listed the differences here for your reference, for details you can refer to the OP Stack documents.

    Our goal is to provide a scaling solution for network congestion problems for highly active applications on the BSC, such as DeFi, NFTs and gaming. opBNB is based on OP Stack and with optimizations of the mining process and the cache data access to achieve a capacity of 100M gas per second, which is much higher than BSC.

    opBNB BSC Ethereum Gas Token BNB BNB ETH VM EVM EVM EVM Gas Price Model EIP-1559 Gas Price Auction EIP-1559 Block Gas Limit 100M 140M 30M Block time 1s 3s 12s Transaction Cost $0.001 $0.03 $1

    Unlike opBNB and OP Mainnet, which have fixed blocktimes, Arbitrum has a variable blocktime that depends on the number and gas of transactions in a block. The more transactions and gas a block contains, the longer it takes to mine. The minimum blocktime on Arbitrum is 0.25 seconds, which means that the fastest block can be mined in a quarter of a second.

    "},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/","title":"Protocol Addresses","text":""},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#opbnb-protocol-addresses","title":"opBNB Protocol addresses","text":"

    The opBNB protocol contracts are smart contracts that enable the execution of transactions on the opBNB network. The main contracts are:

    Testnet:

    Name Address Batch Sender 0x1Fd6A75CC72f39147756A663f3eF1fc95eF89495 Batch Inbox 0xfF00000000000000000000000000000000005611 Output Proposer 0x4aE49f1f57358c13A5732cb12e656Cf8C8D986DF

    Mainnet:

    Name Address Batch Sender 0xef8783382eF80Ec23B66c43575A6103dECA909c3 Batch Inbox 0xff00000000000000000000000000000000000204 Output Proposer 0xc235c904AD9EfcABfF4628E3279994A4c0A9d591"},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#_1","title":"Protocol Addresses","text":""},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#l1-contract-addresses","title":"L1 Contract Addresses","text":"

    Testnet

    Name Description Address L1CrossDomainMessenger responsible for facilitating cross-domain communication on Layer 1 (L1) 0x5b0c605c707979e8bDc2Ad9271A0388b3fD4Af3E L1ERC721Bridge This contract is likely an ERC-721 bridge that enables the transfer of non-fungible tokens (NFTs) between L1 and L2 0xad39e2cfa7d8d8B6c2d56244Bfb88990EC31Bb79 L1ERC721BridgeProxy A proxy contract that may provide additional functionalities for the L1ERC721Bridge contract. 0x17e1454015bFb3377c75bE7b6d47B236fd2ddbE7 L1StandardBridge A standard bridge contract that enables the transfer of fungible tokens between L1 and L2. 0xddB9EB847971DaA82e5dbe2745C429A3B2715B46 L2OutputOracle This contract is an oracle on Layer 2 that provides output data to be used in smart contracts and applications 0xD92aEF4473093C67A7696e475858152D3b2acB7c L2OutputOracleProxy A proxy contract related to the L2OutputOracle, providing an interface or additional functionality. 0xFf2394Bb843012562f4349C6632a0EcB92fC8810 Lib_AddressManager This contract is a library used to manage addresses for various contracts in the system. 0x4d07b9B1ffC70Fc824587573cfb6ef1Cc404AaD7 OptimismMintableERC20Factory This is a factory contract for creating mintable ERC-20 tokens on the Layer 2 network. 0x1AD11eA5426bA3A11c0bA8c4B89fd1BCa732025E OptimismMintableERC20FactoryProxy A proxy contract related to the OptimismMintableERC20Factory, providing an interface or additional functionality. 0x182cE4305791744202BB4F802C155B94cb66163B OptimismPortal This contract serves as a portal or gateway for interacting with the Optimism Layer 2 network. 0x2d5D7bEe8ebEf17DE14dd6ADAE8271507994a6E0 OptimismPortalProxy A proxy contract related to the OptimismPortal, providing an interface or additional functionality. 0x4386C8ABf2009aC0c263462Da568DD9d46e52a31 PortalSender This contract is involved in sending data or messages to a portal or gateway on the L1. 0x02B668393Bc41415Dbb973C9dC144fDD42B8fA2D ProxyAdmin This contract is responsible for managing proxy contracts, allowing for upgrades and access control. 0xE4925bD8Ac30b2d4e2bD7b8Ba495a5c92d4c5156 Proxy__OVM_L1CrossDomainMessenger This contract is a proxy for the L1CrossDomainMessenger contract on the Layer 2, enabling interaction with the Layer 2 contract from Layer 1. 0xD506952e78eeCd5d4424B1990a0c99B1568E7c2C Proxy__OVM_L1StandardBridge This is a proxy for the L1StandardBridge contract on the Layer 2 network, allowing interaction with the Layer 2 bridge from Layer 1. 0x677311Fd2cCc511Bbc0f581E8d9a07B033D5E840 SystemConfig This contract is responsible for managing system configurations, settings, or parameters in the protocol. 0x8Fc086Ec0ac912D5101Fec3E9ac6D910eBD5b611 SystemConfigProxy A proxy contract related to the SystemConfig contract, providing an interface or additional functionality. 0x406aC857817708eAf4ca3A82317eF4ae3D1EA23B SystemDictator This contract has a role in managing or governing certain aspects of the system or protocol. 0x281cc8F04AE5bb873bADc3D89059423E4c664834 SystemDictatorProxy A proxy contract related to the SystemDictator contract, providing an interface or additional functionality. 0xB9Edfded1254ca07085920Af22BeCE0ce905F2AB"},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#_2","title":"Protocol Addresses","text":"

    Mainnet

    Name Description Address L1CrossDomainMessenger responsible for facilitating cross-domain communication on Layer 1 (L1) 0x09525eB7eEd671582dDc6f02f8D9082cbd55A606 L1ERC721Bridge This contract is likely an ERC-721 bridge that enables the transfer of non-fungible tokens (NFTs) between L1 and L2 0xCB4CD5B74A2f2D75076Fb097Da70cEF5FEaC0428 L1ERC721BridgeProxy A proxy contract that may provide additional functionalities for the L1ERC721Bridge contract. 0xC7c796D3B712ad223Bc29Bf85E6cdD3045D998C4 L1StandardBridge A standard bridge contract that enables the transfer of fungible tokens between L1 and L2. 0x6df37de57D50eC5a0600510eB8F563F538BDc403 L2OutputOracle This contract is an oracle on Layer 2 that provides output data to be used in smart contracts and applications 0x0d61A015BAeF63f6740afF8294dAc278A494f6fA L2OutputOracleProxy A proxy contract related to the L2OutputOracle, providing an interface or additional functionality. 0x153CAB79f4767E2ff862C94aa49573294B13D169 Lib_AddressManager This contract is a library used to manage addresses for various contracts in the system. 0x29cfb9A803589Ff5C37f955ead83b45311F15b12 OptimismMintableERC20Factory This is a factory contract for creating mintable ERC-20 tokens on the Layer 2 network. 0x6560F2822c9dFb9801F5E9A7c7CE1564c8c2b461 OptimismMintableERC20FactoryProxy A proxy contract related to the OptimismMintableERC20Factory, providing an interface or additional functionality. 0xAa53ddCDC64A53F65A5f570cc13eB13529d780f1 OptimismPortal This contract serves as a portal or gateway for interacting with the Optimism Layer 2 network. 0x7e2419F79c9546B9A0E292Fd36aC5005ffed5495 OptimismPortalProxy A proxy contract related to the OptimismPortal, providing an interface or additional functionality. 0x1876EA7702C0ad0C6A2ae6036DE7733edfBca519 PortalSender This contract is involved in sending data or messages to a portal or gateway on the L1. 0xEDa034A4B7806e1283e99F8522eFd08d855B9b72 ProxyAdmin This contract is responsible for managing proxy contracts, allowing for upgrades and access control. 0x27a591Ec09AAfEEb39d7533AEf7C64E0305D1576 Proxy__OVM_L1CrossDomainMessenger This contract is a proxy for the L1CrossDomainMessenger contract on the Layer 2, enabling interaction with the Layer 2 contract from Layer 1. 0xd95D508f13f7029CCF0fb61984d5dfD11b879c4f Proxy__OVM_L1StandardBridge This is a proxy for the L1StandardBridge contract on the Layer 2 network, allowing interaction with the Layer 2 bridge from Layer 1. 0xF05F0e4362859c3331Cb9395CBC201E3Fa6757Ea SystemConfig This contract is responsible for managing system configurations, settings, or parameters in the protocol. 0x0be96fcB5eCCA87c775344fB76A3A1C6146cA5Fd SystemConfigProxy A proxy contract related to the SystemConfig contract, providing an interface or additional functionality. 0x7AC836148C14c74086D57F7828F2D065672Db3B8 SystemDictator This contract has a role in managing or governing certain aspects of the system or protocol. 0x0744F61646DdE7Bc2d2c18B13D08a8fba597666b SystemDictatorProxy A proxy contract related to the SystemDictator contract, providing an interface or additional functionality. 0xEb23CCD85eF040BdAf3CBf962C816cD9Cb691F35"},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#_3","title":"Protocol Addresses","text":""},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#l2-contract-addresses","title":"L2 Contract Addresses","text":"Name Description Address WBNB This contract represents Wrapped BNB, a token that is pegged to BNB on the opBNB network. 0x4200000000000000000000000000000000000006 L2CrossDomainMessenger This contract is responsible for facilitating cross-domain communication on Layer 2 of the opBNB network. 0x4200000000000000000000000000000000000007 L2StandardBridge This contract is a standard bridge on Layer 2, enabling the transfer of fungible tokens between different chains or networks. 0x4200000000000000000000000000000000000010 SequencerFeeVault This contract serves as a vault for collecting fees from sequencers, who are responsible for submitting transactions on opBNB. 0x4200000000000000000000000000000000000011 OptimismMintableERC20Factory This is a factory contract for creating mintable ERC-20 tokens on the Layer 2 network. 0x4200000000000000000000000000000000000012 GasPriceOracle This contract may provide gas price data to be used in transactions and fee calculations on the opBNB network. 0x420000000000000000000000000000000000000F L1Block This contract represents a block on Layer 1 in the context of interacting with opBNB. 0x4200000000000000000000000000000000000015 L2ToL1MessagePasser This contract is responsible for passing messages from Layer 2 to Layer 1 on the opBNB network. 0x4200000000000000000000000000000000000016 L2ERC721Bridge This contract is a bridge for transferring ERC-721 non-fungible tokens on Layer 2. 0x4200000000000000000000000000000000000014 OptimismMintableERC721Factory This is a factory contract for creating mintable ERC-721 tokens on the Layer 2 network. 0x4200000000000000000000000000000000000017 ProxyAdmin This contract is responsible for managing proxy contracts on the opBNB network, allowing for upgrades and access control. 0x4200000000000000000000000000000000000018 BaseFeeVault This contract acts as a vault for collecting base fees on the opBNB network. 0x4200000000000000000000000000000000000019 L1FeeVault This contract serves as a vault for collecting fees on Layer 1 in the context of interacting with opBNB. 0x420000000000000000000000000000000000001a"},{"location":"bnb-opbnb/core-concepts/opbnb-protocol-addresses/#reference","title":"reference","text":""},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/","title":"Optimizations on OP Stack - opBNB","text":"

    This document discusses the various optimizations made to OP Stack that enhances its performance and helps in offering super cheap gas fees.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#opbnb-offers-enhanced-performance-and-cheap-gas-fees","title":"opBNB offers enhanced performance and cheap gas fees","text":"

    opBNB enhances the performance of the \u201cExecution Layer\u201d and the \u201cDerivation Layer\u201d of the OP Stack as highlighted in OP Stack landscape.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#optimization-of-execution-layer","title":"Optimization of Execution Layer","text":"

    One of the main challenges in developing the opBNB protocol was to ensure a high throughput of transactions. To achieve this, opBNB leveraged execution optimization techniques that had previously been implemented for BSC.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#evm-state-data-access-optimization","title":"EVM State Data Access Optimization","text":"

    Before we dive into the details of the optimisations, let\u2019s see how EVM handles the state data. The diagram below illustrates how the EVM accesses state data. The EVM first checks the cache in memory for the data. If the data is not there, the EVM uses the LevelDB, which involves disk IO.

    By improving cache efficiency and accelerating database reads and writes, opBNB realizes substantial performance and scalability gains that benefit both node operators and end users.

    (Compared with standard Ethereum world state data storage model, BNB introduced the \u201cSharedPool\u201d as L1.5 cache to improve the hit rate of cache)

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#increased-accuracy-of-bloom-filter-in-l2-diff-layer","title":"Increased accuracy of Bloom Filter in L2: Diff Layer","text":"

    Avoiding unnecessary recursive accesses to cache by increasing the accuracy of Bloom Filter in L2: Diff Layer Bloom filters are a probabilistic data structure that can rapidly verify if an element exists within a data set. To access the state data, EVM uses the bloom filter to verify if the key-value pair is in the Diff Layer and then searches the cache recursively until it finds them, otherwise, EVM directly reads the data from the levelDB.

    However, bloom filters may yield false positives. Moreover, the rate of false positives increases as the dataset bloom filters evaluate expands. Given the opBNB dataset is larger than Ethereum\u2019s, the potential for false positives could be greater as well.

    The false positive can result in the unnecessary recursive access. To mitigate this, opBNB reduced the diff layer level from the default of 128 to a configurable parameter set at 32. This reduction decreases the size of the dataset, in turn diminishing the possibility of false positives to avoid the unnecessary time consuming operations to increase the efficiency of state retrieval.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#effective-prefetch-in-the-cache-model-of-l15-and-its-upper-layers","title":"Effective Prefetch in the cache model of L1.5 and its upper layers","text":"

    Prefetch is a technique that enhances the performance of transaction execution by loading data from disk to cache in advance. When a block needs to be processed in full sync mode or mined in mining mode, the opBNB node launches N threads to perform state prefetch.

    The threads execute the transactions of a block or TxPool and discard the results, but keep the data items in the cache. This way, when the node needs to access the data, it is more likely to find it in the cache rather than on disk, which improves the cache hit rate.

    However, the original prefetch design had a performance limitation. It used separate state databases for the prefetch and the main processes. The prefetch threads could only store the prefetched data in the L2 diff layer (See the 3 layer cache model that was explained before). To access this data, the main process had to traverse the L1, L2, and probably L3 layers, which was too slow for a high performance layer 2 chain.

    The new design improves performance by sharing a pool that holds the whole world state (originStorage) between the prefetch and the main EVM processes. This way, the prefetch threads can put the prefetched data right into the L1.5 (the upper layer of the cache model), which makes it faster for the main process to access. See the detailed process below.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#mining-process-optimization","title":"Mining Process Optimization","text":"

    The process of mining L2 blocks of OP Stack is illustrated in the diagram. It involves a loop where the Rollup Driver (opNode) imports the previous blocks and then invokes the Engine API (op-geth) to produce new blocks on Layer 2.

    The Rollup Driver (opNode) initiates the block generation process on op-geth by calling the engine_forkChoiceUpdatedv1 API of the Engine API(op-geth). This instructs Engine API(op-geth) to start producing an initial block by executing the transactions. (See \u201cEngine API: Initiate block production\u201d in the diagram). The Engine API(op-geth) then returns a payload ID to the Rollup Driver (opNode).

    However, when Engine API(op-geth) receives the engine_newPayloadV1 call from the Rollup Driver (opNode) to commit the block, it has to execute the transactions again, which is redundant and time-consuming. It can take hundreds of milliseconds to complete.

    To optimize the performance, we added a cache layer to store the execution results during the initial block production step. This way, when op-geth receives the engine_newPayloadV1 call, it can retrieve the data from the cache instead of executing the transactions again. This saves time and resources for the system.

    "},{"location":"bnb-opbnb/core-concepts/optimisations-on-opstack/#optimization-of-derivation-layer","title":"Optimization of Derivation Layer","text":"

    The batcher performance bottleneck was caused by the need to wait for 15 blocks (45 seconds) on Layer 1 (BSC) to confirm each batch of transactions before submitting the next one. This was due to the possibility of reorg on Layer 1 chain. To solve this problem, we introduced the asynchronous submission feature, which allows the batcher to submit batches without waiting for confirmation.

    A separate monitor process keeps track of Layer 1 and notifies the batcher if a reorg happens, so that the batcher can resubmit the affected transactions. This feature improves the efficiency of the batcher. It is not yet available on testnet and is still under development, but it will be deployed on opBNB mainnet.

    "},{"location":"bnb-opbnb/core-concepts/raas/","title":"Rollup as a Service (RaaS) on BNB Chain - opBNB","text":""},{"location":"bnb-opbnb/core-concepts/raas/#what-is-rollup-as-a-service","title":"What is Rollup as a Service","text":"

    Rollup-as-a-Service (RaaS) represents a transformative approach in the blockchain sphere, akin to Software-as-a-Service (SaaS) in the cloud computing domain, tailored specifically for decentralized applications (dApps) and blockchain projects. This innovative service model offers a cost-effective and efficient pathway for projects to build and deploy rollup networks.

    "},{"location":"bnb-opbnb/core-concepts/raas/#alignment-with-bnb-chains-roadmap-and-ecosystem-growth","title":"Alignment with BNB Chain\u2019s Roadmap and Ecosystem Growth","text":"

    The demand for RaaS within the BNB Chain ecosystem is not just a trend; it\u2019s a strategic response to the need for higher transaction throughput and enhanced scalability. As the chain eyes substantial growth, RaaS stands out as an essential service that supports this expansion. It does so by enabling developers to deploy scalable applications with ease, leveraging rollup technology to process transactions on Layer 2 network before finalizing them on the main blockchain(BSC).

    "},{"location":"bnb-opbnb/core-concepts/raas/#building-with-raas-aligned-with-bnb-chains-future","title":"Building with RaaS Aligned with BNB Chain\u2019s Future","text":"

    Building with Rollup as a Service (RaaS) on the BNB Chain involves leveraging specialized services from providers like NodeReal, AltLayer, Movement Labs, Lumoz, and 4everland, each offering unique tools to enhance blockchain application development. By adopting these specialized RaaS solutions, developers can leverage the strengths of the BNB Chain ecosystem to create innovative, reliable, and user-centric blockchain applications.

    Service Provider Developer tools and tech stack How to Start NodeReal E2E professional service with infrastructure support, including, indexing service, multi-sig wallet service, explorer, and other enterprise services. https://nodereal.io/semita Altlayer Versatile rollup-up stack support and no-code setup dashboard https://altlayer.io/ Movement Labs Move based L2 on BSC support https://movementlabs.xyz/ Lumoz Support zkevm on BSC https://lumoz.org/rollups 4EVERLAND One-click deplopyment of rollups on BSC https://docs.4everland.org/raas-beta/whats-rollups"},{"location":"bnb-opbnb/core-concepts/why-bsc-requires-opbnb/","title":"Why BSC Requires opBNB - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/why-bsc-requires-opbnb/#why-bsc-requires-opbnb","title":"Why BSC Requires opBNB","text":"

    Layer 1 networks are the base networks that provide the infrastructure for data transmission and validation, such as BSC and Ethereum. These networks face the challenge of network congestion during peak periods, which usually happens when any popular application runs a promotion campaign or experiences a spike in traffic. Network congestion can lead to high transaction fees, slow transactions, and poor user experience.

    To overcome these challenges, layer 1 networks need to improve their scalability, which is the ability to handle more transactions per second without compromising security. For example, BSC had a web3 game on BNB Smart Chain (BSC) in 2021 which generated over 8 million transactions per day.

    1. BSC\u2019s throughput capacity would presumably be vastly exceeded, resulting in slowed transaction speeds, delayed transaction finality, and a poor user experience both for game players and users of other dApps.

    2. Daily gas fees could potentially rise to over 6,800 BNB ($3M USD) at that level of usage, posing a substantial barrier to usability and sustainability of this game.

    The immense transaction loads from a dApp on such a large scale seem infeasible for BSC to handle efficiently in its current form. Significant optimizations and scaling solutions would likely be required for BSC to support such a dApp without network-wide performance degradation and unreasonably high costs.

    "},{"location":"bnb-opbnb/core-concepts/why-opstack/","title":"Why OP Stack - opBNB Core Concepts","text":""},{"location":"bnb-opbnb/core-concepts/why-opstack/#why-op-stack-as-the-foundation-of-opbnb","title":"Why OP Stack as the Foundation of opBNB","text":"

    Our team had extensive discussions and research before we embarked on the mission of creating a high performance optimistic rollup for BNB Smart Chain.

    "},{"location":"bnb-opbnb/core-concepts/why-opstack/#our-goals","title":"Our goals:","text":"

    The OP Stack is a framework for building scalable and interoperable layer-2 solutions based on the utility, simplicity and extensibility principles. By choosing OP Stack as the bedrock of opBNB, we can achieve several benefits, such as:

    "},{"location":"bnb-opbnb/developers/bep20-crosschain/","title":"BEP20 Cross-chain - opBNB Develop","text":""},{"location":"bnb-opbnb/developers/bep20-crosschain/#arbitrary-bep20-cross-chain","title":"Arbitrary BEP20 Cross-chain","text":"

    You can use the opBNB bridge or third-party bridges like zkBridge and rhino.fi to easily deposit and withdraw most mainstream BEP20 tokens on BSC.

    If a token is not supported by these bridges, you have the option to deploy your own L2 mirror token contract on opBNB. This allows for permissionless cross-chain transfer of these tokens.

    This guide will help you deploy your L2 mirror token contract on opBNB and demonstrate how to use it for transferring tokens between BSC and opBNB.

    "},{"location":"bnb-opbnb/developers/bep20-crosschain/#deploying-a-l2-mirror-token-contract","title":"Deploying a L2 Mirror Token Contract","text":"

    There is a pre-deployed OptimismMintableERC20Factory contract on opBNB that allows you to deploy a L2 token by calling a function of the factory contract. The address of the contract is 0x4200000000000000000000000000000000000012.

    The function signature and the emitted event are as follows:

    /**\n    * @notice Emitted whenever a new OptimismMintableERC20 is created.\n    *\n    * @param localToken  Address of the created token on the local chain.\n    * @param remoteToken Address of the corresponding token on the remote chain.\n    * @param deployer    Address of the account that deployed the token.\n    */\nevent OptimismMintableERC20Created(\n    address indexed localToken,\n    address indexed remoteToken,\n    address deployer\n);\n\n/**\n    * @notice Creates an instance of the OptimismMintableERC20 contract.\n    *\n    * @param _remoteToken Address of the token on the remote chain.\n    * @param _name        ERC20 name.\n    * @param _symbol      ERC20 symbol.\n    *\n    * @return Address of the newly created token.\n    */\nfunction createOptimismMintableERC20(\n    address _remoteToken,\n    string memory _name,\n    string memory _symbol\n) public returns (address) {}\n

    _remoteToken is the address of the token on the remote chain, which is BSC in this case. _name and _symbol should be the same with the name and symbol of the token on BSC. The decimal of the token on opBNB is always 18.

    Here is the transaction that generates the FDUSD token on opBNB.

    Warning: It does not support certain BEP20 configurations: - Fee on transfer tokens - Tokens that modify balances without emitting a Transfer event

    "},{"location":"bnb-opbnb/developers/bep20-crosschain/#cross-chain-transfer-with-js-sdk","title":"Cross-chain Transfer with JS SDK","text":"

    Once you have deployed your own L2 mirror token contract, you can use the JS SDK to transfer tokens between BSC and opBNB.

    The following script is a TypeScript demo script. It uses ethers.js and @eth-optimism/sdk to transfer tokens between BSC and opBNB.

    You can save the script as erc20CrosschainTransfer.ts and run it with the following command(ensure that you have installed deno):

    deno run -A erc20CrosschainTransfer.ts\n

    Feel free to modify the script to suit your needs.

    import { Contract, ethers, Signer, Wallet } from \"npm:ethers@^5\";\nimport \"https://deno.land/x/dotenv/load.ts\";\nimport { CrossChainMessenger, ETHBridgeAdapter } from \"npm:@eth-optimism/sdk\";\nimport * as optimismSDK from \"npm:@eth-optimism/sdk\";\n\nconst gwei = BigInt(1e9);\nconst BridgeConfigTestnet = {\n  l1URL: \"https://bsc-testnet.bnbchain.org\",\n  l2URL: \"https://opbnb-testnet-rpc.bnbchain.org\",\n  l1ChainID: 97,\n  l2ChainID: 5611,\n  contracts: {\n    AddressManager: \"0x0000000000000000000000000000000000000000\",\n    StateCommitmentChain: \"0x0000000000000000000000000000000000000000\",\n    CanonicalTransactionChain: \"0x0000000000000000000000000000000000000000\",\n    BondManager: \"0x0000000000000000000000000000000000000000\",\n    L1CrossDomainMessenger: \"0xD506952e78eeCd5d4424B1990a0c99B1568E7c2C\",\n    L1StandardBridge: \"0x677311Fd2cCc511Bbc0f581E8d9a07B033D5E840\",\n    OptimismPortal: \"0x4386C8ABf2009aC0c263462Da568DD9d46e52a31\",\n    L2OutputOracle: \"0xFf2394Bb843012562f4349C6632a0EcB92fC8810\",\n  },\n  l1GasPrice: 5n * gwei,\n  l1Explorer: \"https://testnet.bscscan.com\",\n  l2Explorer: \"https://testnet.opbnbscan.com\",\n};\n\nconst BridgeConfigMainnet = {\n  l1URL: \"https://bsc-dataseed.bnbchain.org\",\n  l2URL: \"https://opbnb-mainnet-rpc.bnbchain.org\",\n  l1ChainID: 56,\n  l2ChainID: 204,\n  contracts: {\n    AddressManager: \"0x0000000000000000000000000000000000000000\",\n    StateCommitmentChain: \"0x0000000000000000000000000000000000000000\",\n    CanonicalTransactionChain: \"0x0000000000000000000000000000000000000000\",\n    BondManager: \"0x0000000000000000000000000000000000000000\",\n    L1CrossDomainMessenger: \"0xd95D508f13f7029CCF0fb61984d5dfD11b879c4f\",\n    L1StandardBridge: \"0xF05F0e4362859c3331Cb9395CBC201E3Fa6757Ea\",\n    OptimismPortal: \"0x7e2419F79c9546B9A0E292Fd36aC5005ffed5495\",\n    L2OutputOracle: \"0x0d61A015BAeF63f6740afF8294dAc278A494f6fA\",\n  },\n  l1GasPrice: 3n * gwei,\n  l1Explorer: \"https://bscscan.com\",\n  l2Explorer: \"https://opbnbscan.com\",\n};\n\nconst BridgeConfig = BridgeConfigTestnet;\n\nconst privateKey = Deno.env.get(\"PRIVATE_KEY\")!;\nconst l1RpcProvider = new ethers.providers.JsonRpcProvider(BridgeConfig.l1URL);\nconst l2RpcProvider = new ethers.providers.JsonRpcProvider(BridgeConfig.l2URL);\nconst wallet = new Wallet(privateKey);\nconst l1Signer = wallet.connect(l1RpcProvider);\nconst l2Signer = wallet.connect(l2RpcProvider);\nlet crossChainMessenger: CrossChainMessenger;\n\nconst l1BUSDAddr = \"0xeD24FC36d5Ee211Ea25A80239Fb8C4Cfd80f12Ee\";\nconst l2BUSDAddr = \"0xa9aD1484D9Bfb27adbc2bf50A6E495777CC8cFf2\";\n\nfunction setup() {\n  crossChainMessenger = new CrossChainMessenger({\n    l1ChainId: BridgeConfig.l1ChainID,\n    l2ChainId: BridgeConfig.l2ChainID,\n    l1SignerOrProvider: l1Signer,\n    l2SignerOrProvider: l2Signer,\n    bedrock: true,\n    contracts: {\n      l1: BridgeConfig.contracts,\n      l2: optimismSDK.DEFAULT_L2_CONTRACT_ADDRESSES,\n    },\n  });\n  const ethBridgeAdapter = new ETHBridgeAdapter(\n    {\n      messenger: crossChainMessenger,\n      l1Bridge: BridgeConfig.contracts.L1StandardBridge,\n      l2Bridge: \"0x4200000000000000000000000000000000000010\",\n    },\n  );\n  crossChainMessenger.bridges.ETH = ethBridgeAdapter;\n}\n\nasync function depositERC20() {\n  const tx = await crossChainMessenger.depositERC20(l1BUSDAddr, l2BUSDAddr, 1, {\n    overrides: {\n      gasPrice: BridgeConfig.l1GasPrice,\n    },\n  });\n  await tx.wait();\n  console.log(\n    `depositBNB Transaction hash (on L1): ${BridgeConfig.l1Explorer}/tx/${tx.hash}`,\n  );\n  console.log(\n    `please check ${BridgeConfig.l2Explorer}/address/${l1Signer.address}?tab=deposit&p=1 for the deposit txn on L2`,\n  );\n}\n\nasync function withdrawERC20(): Promise<string> {\n  const tx = await crossChainMessenger.withdrawERC20(\n    l1BUSDAddr,\n    l2BUSDAddr,\n    1,\n    {\n      overrides: {\n        maxPriorityFeePerGas: 1,\n        maxFeePerGas: 10000,\n      },\n    },\n  );\n  await tx.wait();\n  console.log(\n    `withdrawBNB Transaction hash (on L2): ${BridgeConfig.l2Explorer}/tx/${tx.hash}`,\n  );\n  return tx.hash;\n}\n\nasync function proveWithdrawal(hash: string, wait: boolean = true) {\n  while (true) {\n    try {\n      const tx = await crossChainMessenger.proveMessage(hash, {\n        overrides: {\n          gasPrice: BridgeConfig.l1GasPrice,\n        },\n      });\n      await tx.wait();\n      console.log(\n        `proveWithdrawal Transaction hash (on L1): ${BridgeConfig.l1Explorer}/tx/${tx.hash}`,\n      );\n      break;\n    } catch (error) {\n      console.log(error.message);\n      if (error.message.includes(\"state root for message not yet published\")) {\n        if (wait) {\n          console.log(\n            `Waiting for status to be READY_TO_PROVE, current time: ${new Date()}`,\n          );\n        } else {\n          throw error;\n        }\n      } else {\n        throw error;\n      }\n    }\n  }\n}\n\nasync function finalizeWithdrawal(hash: string, wait: boolean = true) {\n  while (true) {\n    try {\n      const tx = await crossChainMessenger.finalizeMessage(hash, {\n        overrides: {\n          gasPrice: BridgeConfig.l1GasPrice,\n        },\n      });\n      await tx.wait();\n      console.log(\n        `finalizeWithdrawal Transaction hash (on L1): ${BridgeConfig.l1Explorer}/tx/${tx.hash}`,\n      );\n      break;\n    } catch (error) {\n      if (\n        error.message.includes(\n          \"proven withdrawal finalization period has not elapsed\",\n        )\n      ) {\n        if (wait) {\n          console.log(\n            `Waiting for status to be READY_TO_FINALIZE, current time: ${new Date()}`,\n          );\n        } else {\n          throw error;\n        }\n      } else {\n        throw error;\n      }\n    }\n  }\n}\n\nasync function main() {\n  console.log(\"opbnbBridge demo\");\n\n  setup();\n  // deposit ERC20\n  await depositERC20()\n\n  // withdraw ERC20\n  const hash = await withdrawERC20();\n  await proveWithdrawal(hash);\n  await finalizeWithdrawal(hash);\n}\n\nawait main();\n
    "},{"location":"bnb-opbnb/developers/cheat-sheet/","title":"Hardware Requirements - opBNB Develop","text":""},{"location":"bnb-opbnb/developers/cheat-sheet/#hardware-requirements","title":"Hardware Requirements","text":"

    Setting up a node in the BNB Chain ecosystem requires understanding hardware requirements. The Minimum Hardware Requirement ensures efficient management of average transaction volumes, while the Recommended Hardware Requirement caters to high performance, capable of processing up to 100 million gas per second and handling 1k QPS (Query Per Second), ideal for heavy transaction loads or peak efficiency.

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#processor","title":"Processor","text":"

    CPU Type: Intel Xeon Scalable processors (Ice Lake) or newer

    op-node:

    op-geth:

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#memory","title":"Memory","text":"

    op-node:

    op-geth:

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#storage","title":"Storage","text":"

    op-node:

    op-geth:

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#network","title":"Network","text":""},{"location":"bnb-opbnb/developers/cheat-sheet/#running-your-own-opbnb-node","title":"Running Your Own opBNB Node","text":""},{"location":"bnb-opbnb/developers/cheat-sheet/#performance-stability-optimization","title":"Performance Stability Optimization","text":"

    L1 RPC Configuration:

    Configure multiple L1 RPC endpoints for op-node setups on L2 solutions like opBNB to ensure synchronization with the L1 chain, security, data integrity, and reduced risk of single point of failure.

    For example:

      export L1_RPC1=https://bsc-dataseed.bnbchain.org\n  export L1_RPC2=https://bsc.nodereal.io\n  --l1=rpc1,rpc2\u2026\n
    Optimize L1 receipt retrieval performance

    L2 Sync Mode Settings:

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#node-health-monitoring","title":"Node Health Monitoring","text":""},{"location":"bnb-opbnb/developers/cheat-sheet/#import-json-model","title":"Import JSON Model","text":"

    Monitor your node\u2019s health by importing the rpc_nodes.json model.

    "},{"location":"bnb-opbnb/developers/cheat-sheet/#important-metrics","title":"Important Metrics","text":""},{"location":"bnb-opbnb/developers/developer-tools/","title":"Developer Tools - opBNB Develop","text":"

    One of our main objectives is to expand the adoption and utility of opBNB as a high performance and low cost Layer 2 chain on the BNB Smart Chain. To achieve this goal, we have to ensure that our underlying technology is robust, scalable and user-friendly. That is why we are committed to developing and improving the core infrastructure and tools that support opBNB and its community of users, hosts and developers. Below are the ecosystem we are building for the opBNB.

    "},{"location":"bnb-opbnb/developers/developer-tools/#summary","title":"Summary","text":"Categories Sub Categories Infrastructure and Toolings DAO Governance DAO Governance XDao,Snapshot Node Providers Node Provider NodeReal Explorer Explorer NodeReal opBNB Scan, BSCScan Developer Platforms Truffle, Foundry, Hardhat, Remix Use Access Tooling Wallet Binance Web3 Wallet, Metamask, TrustWallet, Particle Network, Gem Wallet, OKX Wallet, MathWallet, Sequence.build, Avatar, Openfort Bridges opBNB Bridge,PolyHedra, rhino.fi dApp Store dApp Bay Oracles Price Feeds, VRF Binance Oracle, Supra Storage Decentralized Storage BNB Greenfield Security AvengerDAO Account Abstraction Particle Network, Biconomy, CyberConnect, Openfort MultiSig BNB Chain Multi-Sig Wallet Data Analytics DefiLlama, CoinGecko, DappBay Indexing NodeReal\u2019s opBNB Graph QL NFT NFT Marketplace Element\u2019s NFT Marketplace"},{"location":"bnb-opbnb/developers/developer-tools/#binance-exchange-support","title":"Binance Exchange Support","text":"

    Binance has supported deposit and withdrawal on 7th Nov, 2023. The initial list is BNB, FDUSD, and USDT as a start.

    "},{"location":"bnb-opbnb/developers/developer-tools/#node-providers","title":"Node Providers","text":"

    Needless to mention that the stability of RPC nodes is crucial to any blockchain, in this instance BNB Chain has NodeReal who is one of opBNB early and core contributors to anchor this task.

    NodeReal RPC can be accessed through their API marketplace. For common/public nodes, communities can access BNB ChainList.

    "},{"location":"bnb-opbnb/developers/developer-tools/#wallet","title":"Wallet","text":"

    Crypto/Digital wallet serves as an entry point for users to access blockchain. opBNB have known wallets providing access to opBNB such as Metamask and Trustwallet, leading the front.

    On Account Abstraction(AA), CyberConnect, Particle Network, Biconomy, Openfort has already integrated with opBNB.

    MultiSig wallet BNB Chain has provided its own Safe Multi-Sig Wallet.

    "},{"location":"bnb-opbnb/developers/developer-tools/#wallet-as-a-servicewaas","title":"Wallet as a Service[WaaS]","text":"

    Wallet-as-a-Service (WaaS) streamlines the integration of digital wallets into applications, allowing businesses to manage cryptocurrencies and tokens effortlessly. By handling the complexities of wallet infrastructure, WaaS enables a secure and user-friendly experience for managing digital assets, fostering wider blockchain adoption and enhancing operational efficiency.

    Below wallet have supported Wallet-as-a-Service (WaaS) platforms on the BNB Smart Chain and opBNB, facilitating seamless integration of digital wallet functionalities into applications for managing opBNB and other assets.

    Project Name Main Website WaaS Document Particle Network https://particle.network/ https://particle.network/wallet-introduction.html Sequence.build https://sequence.xyz/ https://sequence.build/landing Avatar Wallet https://avatarwallet.io/ https://docs.avatarwallet.io/docs/introduction Openfort https://openfort.xyz/ https://openfort.xyz/docs ## Bridges

    For bridges opBNB has its own default bridge, which is built mirroring OP Stack. This also means that it has the 7 days challenge period, similar to OP bridge, BASE bridge. But opBNB does have 3rd party bridge providers, such as Polyhedra and Rhino.Fi that provide shorter withdrawal periods.

    "},{"location":"bnb-opbnb/developers/developer-tools/#data-analytics","title":"Data Analytics","text":"

    Several known industry platform already started supporting opBNB, i.e. DefiLlama , CoinGecko, DappBay. For listing on DappBay, projects can fill up this form.

    "},{"location":"bnb-opbnb/developers/developer-tools/#data-indexing","title":"Data Indexing","text":"

    opBNB currently has NodeReal\u2019s opBNB Graph QL as the initial support[Beta Version] as current players such as TheGraph have their pipeline full for the rest of the year. For projects needing such services, projects can liaise with NodeReal on specs, requirements. [Process Link]

    "},{"location":"bnb-opbnb/developers/developer-tools/#dao","title":"DAO","text":"

    Essential component as the BNB Chain moves towards decentralization. XDao and Snapshot are now supporting opBNB.

    "},{"location":"bnb-opbnb/developers/developer-tools/#for-defi-specific","title":"For DeFi Specific","text":""},{"location":"bnb-opbnb/developers/developer-tools/#oracle","title":"Oracle","text":"

    Binance Oracle has started supporting opBNB since Day1. Feel free to reach Binance Oracle for product support and demo.

    "},{"location":"bnb-opbnb/developers/developer-tools/#for-gamesocial-media","title":"For Game/Social Media","text":""},{"location":"bnb-opbnb/developers/developer-tools/#vrf","title":"VRF","text":"

    Binance Oracle has support for opBNB VRF. Feel free to reach Binance Oracle for product support and demo.

    "},{"location":"bnb-opbnb/developers/developer-tools/#nft-marketplace-minting","title":"NFT Marketplace & Minting","text":"

    Element\u2019s NFT Marketplace is already live on opBNB. Minting feature will be ready soon in Nov.

    "},{"location":"bnb-opbnb/developers/geth-sync/","title":"Geth P2P Sync - opBNB Develop","text":""},{"location":"bnb-opbnb/developers/geth-sync/#geth-p2p-sync-feature","title":"Geth P2P Sync Feature","text":"

    We\u2019re excited to introduce a new feature in this release: The Geth P2P Sync Feature. This feature significantly enhances the speed of block data synchronization by leveraging peer-to-peer syncing among geth nodes, as opposed to the previous method of deriving transactions from L1 for each synchronization.

    "},{"location":"bnb-opbnb/developers/geth-sync/#benefits-of-geth-p2p-sync-feature","title":"Benefits of Geth P2P Sync Feature","text":"

    The Geth P2P Sync Feature greatly accelerates block data synchronization. Our tests on the testnet have shown impressive results:

    These improvements can save considerable time and resources, thus improving the overall performance of your operations.

    "},{"location":"bnb-opbnb/developers/geth-sync/#configurations-for-geth-p2p-sync-feature","title":"Configurations for Geth P2P Sync Feature","text":""},{"location":"bnb-opbnb/developers/geth-sync/#new-configurations-op-node","title":"New Configurations (op-node)","text":"

    The above settings are essential for enabling the Geth P2P Sync Feature. Please ensure that these settings are correctly configured in your op-node.

    "},{"location":"bnb-opbnb/developers/geth-sync/#existing-configurations-op-geth","title":"Existing Configurations (op-geth)","text":"

    You can select either of the two options for the syncmode:

    1. full (Recommended): This mode performs a full sync and executes each block. The sync time has been significantly reduced with the new Geth P2P Sync Feature, taking about 15 hours on the testnet (latest height: 10 million).
    2. snap: This mode performs a snapshot sync, which does not execute transactions but still maintains data completeness. This mode is recommended when your P2P peer nodes are trustworthy. The sync time is about 1 hour on the testnet.

    For the bootnodes configuration, you can use the following geth bootnode nodes:

    Ensure the above configurations are correctly set up to fully benefit from the new Geth P2P Sync Feature in this release. We hope you find this feature advantageous. Your feedback is always welcome.

    "},{"location":"bnb-opbnb/developers/multisig-wallet/","title":"Multi-sig Wallet","text":""},{"location":"bnb-opbnb/developers/multisig-wallet/#bnb-chain-safe-multi-sig-wallet-service","title":"BNB Chain Safe Multi-Sig Wallet Service","text":"

    BNB Chain deployed a multi-sig wallet service based on the Gnosis Safe protocol on opBNB mainnet, opBNB testnet and BSC testnet. It provides users with a secure and convenient way to manage their digital assets and transactions.

    "},{"location":"bnb-opbnb/developers/multisig-wallet/#how-to-use-the-bnb-chain-multi-sig-wallet-service","title":"How to Use the BNB Chain Multi-Sig Wallet Service","text":"

    To use the BNB Chain multi-sig wallet service, connect with your own EOA wallet to start. Visit https://multisig.bnbchain.org/welcome

    Read the Safe Doc for details.

    "},{"location":"bnb-opbnb/developers/multisig-wallet/#safe-transaction-service-api","title":"Safe Transaction Service API","text":"

    To create or list safe transactions programmatically, use the Safe Transaction Service API. Here are the endpoints for the opBNB testnet and opBNB mainnet:

    Testnet: https://safe-transaction-opbnb-testnet.bnbchain.org/

    Mainnet: https://safe-transaction-opbnb-mainnet.bnbchain.org/

    Read the api-kit Doc for details.

    "},{"location":"bnb-opbnb/developers/network-faucet/","title":"Testnet Faucet - opBNB Develop","text":""},{"location":"bnb-opbnb/developers/network-faucet/#testnet-faucet","title":"Testnet Faucet","text":"

    If you want to test the functionality of the BNB Smart Chain, you will need some testing tokens, such as tBNB and other major tokens like USDC, BUSD, DAI, and wrapped Bitcoin. There are two ways to claim these testing tokens. Please refer to the BSC faucet doc for details. After you claim your tokens, you can transfer your testing assets to opBNB to start testing through testnet bridge.

    "},{"location":"bnb-opbnb/developers/quick-guide/","title":"Quick Guide - opBNB","text":"

    If you\u2019re a developer seeking to build on opBNB, you\u2019ve come to the right place. This document provides all the information you need to develop opBNB applications.

    "},{"location":"bnb-opbnb/developers/quick-guide/#getting-started","title":"Getting Started","text":"

    The opBNB network is the Layer 2 scaling solution for the BNB Smart Chain(BSC) powered by OP Stack.

    If you are brand new to opBNB, you can try start with the guide on creating a fullstack dapp on opBNB. It will familiarize you with the basic steps of deploying a smart contract on opBNB and interacting with it from a dapp.

    opBNB is EVM equivalent so you can feel confident that your existing Ethereum smart contract skills will transfer seamlessly to opBNB. There are a few small differences between Ethereum and opBNB, so make sure to be aware of them. You can refer to the optimism documentation for more information.

    "},{"location":"bnb-opbnb/developers/quick-guide/#connecting","title":"Connecting","text":"

    Here are some resources to help you get connected to the opBNB network:

    "},{"location":"bnb-opbnb/developers/quick-guide/#get-tokens","title":"Get Tokens","text":"

    opBNB is a Layer 2 on BSC, so tokens can be moved between the two chains using bridges. For the testnet, you can use the faucet to obtain some test tokens on BSC and then bridge them to opBNB using the official bridge. For the mainnet, you can bridge tokens from BSC to opBNB using various bridges, or you can withdraw tokens directly from a centralized exchange (CEX) which supports opBNB network(e.g. Binance).

    "},{"location":"bnb-opbnb/developers/quick-guide/#cross-chain-interoperability","title":"Cross-Chain Interoperability","text":"

    To build cross-chain applications between BSC and opBNB, you should understand how cross-chain message passing works. You can refer to the sending data between L1 and L2 guide for more information.

    "},{"location":"bnb-opbnb/developers/quick-guide/#developer-tools","title":"Developer Tools","text":"

    For more tools and details, you can refer to this doc.

    "},{"location":"bnb-opbnb/developers/set-gas-price/","title":"Set Gas Price - opBNB Develop","text":"

    This document shows you how to set the priority price and base price for opBNB transactions in wallet. These prices determine how much you are willing to pay for your transaction to be included in the next block (Priority Gas Price) and how much you are willing to pay for the gas used by your transaction. Setting these prices correctly can help you save money and avoid delays.

    To set the priority price and base price, follow these steps:

    Metamask:

    1. Open your metamask wallet and click on the opBNB network at the top right corner.

    2. Click on the send button and enter the recipient address and the amount of opBNB you want to send.

    3. Before you confirm your transaction, click on the advanced->edit button next to the gas fee section.

    4. You will see two sliders: one for the Max base fee(Gwei) price and one for the Priority Fee(Gwei). The priority price is the amount of opBNB you are willing to pay per unit of gas for your transaction to be included in the next block. The base price is the amount of opBNB you are willing to pay per unit of gas for the gas used by your transaction. The total gas fee is the sum of these two prices multiplied by the gas consumed. The base fee for opBNB transactions is dynamic and depends on the demand for block space. The minimum possible base fee is 0.000000008 gwei. The priority fee, which is paid to the sequencer who includes the transaction in a block, can also be as low as 0.000000001 gwei. However, these fees may vary depending on the network congestion and the urgency of the transaction.

    5. You can adjust the sliders according to your preferences. The higher the priority price, the faster your transaction will be confirmed, but the more expensive it will be. The lower the base price, the cheaper your transaction will be, but the more likely it will fail if the gas limit is too low.

    6. Once you are satisfied with your settings, click on save and then confirm your transaction.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/","title":"Build on opBNB - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-to-check-if-a-smart-contract-is-verified-on-opbnb-using-an-api-get-request","title":"How to check if a smart contract is verified on opBNB using an API GET request?","text":"

    With the API key and smart contract address, you can retrieve the contract\u2019s verification status, source code & ABI.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#why-does-token-info-like-name-symbol-is-not-displayed-on-opbnbscan-despite-having-contract-verified","title":"Why does token info (like name, symbol) is not displayed on opBNBscan despite having contract verified?","text":"

    If the deployed contract is a proxy contract, then the info. will not be displayed as opBNBscan uses enhanced API to fetch the token details like name, symbol etc. In this case, enhanced API needs to call the implementation contract to fetch the token details. Currently, this feature is under development where enhanced API will make call to implementation contract when token info. returned from proxy contract is empty.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-are-the-third-party-provider-services-where-we-can-purchase-private-rpc-access","title":"What are the third-party provider services where we can purchase private RPC access?","text":"

    You can purchase private RPC access from Nodereal.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#are-there-any-grants-or-financial-support-for-projects-on-opbnb","title":"Are there any grants or financial support for projects on opBNB?","text":"

    Yes, we provide the same support for opBNB as for BNB Smart Chain when it comes to grants or financing projects. Check here for the complete details.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#is-there-an-ability-to-run-nodes-on-opbnb","title":"Is there an ability to run nodes on opBNB?","text":"

    Check out the official documentation to learn how to run nodes on opBNB.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#can-a-native-project-on-opbnb-issues-its-token-natively-on-opbnb","title":"Can a native project on opBNB issues its token natively on opBNB?","text":"

    Yes, it is up to the project.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-is-the-recommended-approach-for-launching-projects-should-the-project-be-natively-launched-on-opbnb-and-then-bridged-to-l1-or-the-other-way-around","title":"What is the recommended approach for launching projects, should the project be natively launched on opBNB and then bridged to L1 or the other way around?","text":"

    The choice of L2 or L1 depends on the specific needs of the project. L2 offers better performance and lower cost, so it is advisable to use L2 as the starting point if these factors are important for the project.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#is-there-a-possibility-of-a-shared-sequencerliquidity-with-other-chains-built-on-opstack-in-the-future","title":"Is there a possibility of a shared sequencer/liquidity with other chains built on OPStack in the future?","text":"

    Unfortunately, no, in short term, this is BNB Chain team`s goal yet.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-programming-language-is-used-for-the-opbnb-chain-and-contracts","title":"What programming language is used for the opBNB chain and contracts?","text":"

    The pre-deployed smart contracts are written in Solidity, and opBNB is built with OP Stack framework. For details, please refer to official docs for more details.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#are-there-any-airdrops-for-opbnb","title":"Are there any airdrops for opBNB?","text":"

    We want to clarify that there is NO airdrop planned for opBNB as of now. Please be cautious and aware of any claims or messages suggesting otherwise. Protect yourself from potential scams by staying vigilant and verifying information from official sources.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-oracles-and-vrf-does-opbnb-support","title":"What oracles and VRF does opBNB support?","text":"

    opBNB is a permissionless chain that allows any VRF and oracle services to be integrated. The first two services that have been launched on opBNB are Binance Oracle and Polythera, which provide reliable and secure data feeds for smart contracts.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#what-to-do-if-there-is-trouble-verifying-smart-contract-with-all-available-methods-using-the-httpsopbnbscancomverifycontract","title":"What to do if there is trouble verifying smart contract with all available methods using the https://opbnbscan.com/verifyContract","text":"

    Try using the alternative explorer https://opbnb-testnet.bscscan.com/ for verifying your smart contracts.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-do-we-set-hardhat-verification-parameters-for-opbnb","title":"How do we set hardhat verification parameters for opBNB?","text":"

    Refer to the official Hardhat documentation here

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-does-opbnb-handle-the-storage-and-execution-of-metadata-associated-with-nfts-on-its-optimistic-rollup","title":"How does opBNB handle the storage and execution of metadata associated with NFTs on its optimistic rollup?","text":"

    The process of creating and storing NFTs on the opBNB is similar to other blockchains. You need to have a smart contract that defines the properties and functions of your NFT, and then deploy it on the opBNB. To store the metadata of your NFT, such as the name, description, image, and other attributes, you can use various storage solutions. Some examples are BNB Greenfield, IPFS, and Filecoin.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#why-my-opbnb-node-is-unable-to-catch-up-with-current-blocks","title":"Why my opBNB node is unable to catch up with current blocks?","text":"

    There is a possibility that the node\u2019s chain has been forked and is different from other nodes.

    In the event that the chain is forked due to a hard fork, it is recommended to reset the blockchain and synchronize it with the latest version of the program:

    1. Clear the data directory in OP Geth
    2. Update the opbnb to latest version: git clone -b v0.x.x git@github.com:bnb-chain/opbnb.git
    3. Update the op-geth to latest version: git clone -b v0.x.x git@github.com:bnb-chain/op-geth.git

    Follow the instructions here to re-sync the node. Just note that make sure to use the latest version of opbnb and op-geth, and use the new version genesis.json and rollup.json.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-to-verify-erc1967proxy-upgradeable-contract-on-opbnb-testnet-by-hardhat","title":"How to verify ERC1967Proxy upgradeable contract on opbnb-testnet by Hardhat?","text":"

    You can follow the instructions from How to verify a contract on Etherscan/BscScan/PolygonScan to use the solc-input.json to verify the proxy.

    "},{"location":"bnb-opbnb/faq/build-on-opbnb-faqs/#how-to-get-proxys-constructor-arguments-for-verification","title":"How to get proxy\u2019s constructor arguments for verification?","text":"

    To form _data argument we need:

    1. Function name.
    2. Owner address + argument1 + argument2 + etc. Then copy \u201cEncoded data\u201d, add \u201c0x\u201d at the beginning of the text and past it as _data (Bytes) argument. For details, please refer to openzeppelin docs. An easier way is to look at the input data of the creation transaction for your proxy: https://testnet.opbnbscan.com/tx/0xa287b0b69472cb4961c528b16e799136a520f700b5407595314c3cdd0a21f8d6?tab=overview
    3. You can see that the encoded constructor arguments are at the last portion of the bytecode.
    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/","title":"Cross Chain - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/cross-chain-faqs/#how-does-opbnb-ensure-data-availability-and-security-for-off-chain-transactions","title":"How does opBNB ensure data availability and security for off-chain transactions?","text":"

    opBNB relies on a mechanism called \u201cfraud proofs\u201d to ensure data availability and security. Users can submit proofs on-chain that demonstrate any malicious behavior or incorrect transaction processing on the off-chain optimistic rollup. If a fraud proof is valid, the system can penalize the malicious actor and revert any incorrect state changes.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#who-is-responsible-for-gathering-and-bundling-off-chain-transactions-into-bundles-on-opbnb-network","title":"Who is responsible for gathering and bundling off-chain transactions into bundles on opBNB network?","text":"

    Sequencers are responsible for the aggregation of transactions, computation of the state transitions and submission of these to the rollup contract on BSC.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#what-is-the-role-of-the-aggregator-in-the-opbnb-network","title":"What is the role of the aggregator in the opBNB network?","text":"

    Aggregators are entities responsible for gathering and bundling off-chain transactions into batches. They play a crucial role in opBNB by forming these transaction batches and submitting them to the main BNB chain for validation. Aggregators also generate Merkle proofs for the data they submit, which are essential for the anchoring process.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#can-opbnb-handle-smart-contracts-and-complex-computations-like-the-main-bnb-chain","title":"Can opBNB handle smart contracts and complex computations like the main BNB Chain?","text":"

    The opBNB network is EVM compatible and works identically to BSC from a smart contract developer\u2019s perspective. This means that developers can easily deploy their existing Ethereum or BSC smart contracts on opBNB with minimal changes.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#how-does-opbnb-handle-cross-contract-interactions-and-composability","title":"How does opBNB handle cross-contract interactions and composability?","text":"

    Cross-contract interactions and composability are challenging aspects for optimistic rollups. While opBNB can facilitate cross-contract interactions, the limitations of off-chain processing mean that certain complex composability scenarios might be less efficient or not supported at all. Developers and projects using opBNB need to carefully consider these limitations when designing their applications.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#what-happens-if-theres-a-dispute-about-an-off-chain-transactions-validity","title":"What happens if there\u2019s a dispute about an off-chain transaction\u2019s validity?","text":"

    In the event of a dispute, a \u201cchallenge\u201d period is initiated. During this period, anyone can submit a fraud proof to challenge the validity of an off-chain transaction. If the fraud proof is valid and proves that the transaction was incorrect or malicious, the transaction is reverted on-chain, and the malicious actor might face penalties.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#can-smart-contracts-deployed-on-the-main-bnb-smart-chain-interact-seamlessly-with-applications-on-opbnb-if-yes-how","title":"Can smart contracts deployed on the main BNB Smart Chain interact seamlessly with applications on opBNB? If yes, how?","text":"

    Yes, this is achieved through a set of smart contracts that enable the execution of transactions on the opBNB network. The main contract is the batchInbox contract, which receives batches of transactions from the Sequencer on L1.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#how-to-allow-smart-contract-cross-chain-communication-between-l1-and-l2","title":"How to allow smart contract cross chain communication between L1 and L2?","text":"

    Directly interacting with smart contract functions that exist on L2(opBNB) from L1(BSC), is not possible as all smart contracts on L2 are isolated from L1.

    With that said, there is a way for developers to allow arbitrary message sending by writing their own contracts to build their required business logic. More details here.

    "},{"location":"bnb-opbnb/faq/cross-chain-faqs/#can-i-directly-transfer-assets-between-opbnb-and-greenfield","title":"Can I directly transfer assets between opBNB and Greenfield?","text":"

    Currently, direct cross-chain transfers between opBNB and Greenfield are not supported. However, users can achieve cross-chain transfers between these two networks by conducting a two-step process through the Binance Smart Chain (BSC). This involves transferring assets from opBNB to BSC and then from BSC to Greenfield.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/","title":"Gas and Fees - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#what-is-the-cost-of-transfer-transaction-on-opbnb-and-why-opbnb-hold-capacity-to-enable-the-mass-adoption-of-daily-small-amount-transactions","title":"What is the cost of transfer transaction on opBNB and why opBNB hold capacity to enable the mass adoption of daily small amount transactions?","text":"

    opBNB can make small daily transactions possible because the transaction fees are very low, around $0.005 per transaction. This is much lower than traditional payment methods like credit cards which charge around 1-3% per transaction. The low fees on opBNB make it economical for small purchases and daily transactions.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#what-is-the-link-to-the-canonical-bridge-for-gasstables","title":"What is the link to the canonical bridge for gas/stables?","text":""},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#where-can-we-get-the-token-pricing-for-the-bnb-token-on-opbnb","title":"Where can we get the token pricing for the BNB token on opBNB?","text":"

    You can get the token pricing for BNB on opBNB from Coinmarketcap

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#what-is-the-block-gas-limit-on-opbnb","title":"What is the block gas limit on opBNB?","text":"

    The block gas limit on opBNB is 100M/block, and the block time of opBNB is 1 second.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#how-are-transaction-fees-calculated-on-opbnb","title":"How are transaction fees calculated on opBNB?","text":"

    You can details about the transaction fee calculation from opBNB official docs

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#are-there-any-overheads-to-include-in-the-gas-calculation","title":"Are there any overheads to include in the gas calculation?","text":"

    Yes, there is a fixed overhead for L1 data fee is 2100, and dynamic_overhead(L1 Fee Scala) is 1.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#how-are-data-storage-fees-for-rollups-calculated","title":"How are data storage fees for rollups calculated?","text":"

    The data storage fees for rollups are calculated using the following formula.

    l1_data_fee = l1_gas_price * (tx_data_gas + fixed_overhead) * dynamic_overhead\n\nfixed_overhead = 2100\n\ndynamic_overhead = 1\n\ntx_data_gas = count_zero_bytes(tx_data) * 4 + count_non_zero_bytes(tx_data) * 16\n
    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#what-gas-fees-are-associated-with-withdrawing-opbnb-assets-from-the-main-chain-back-to-the-layer-2-network","title":"What gas fees are associated with withdrawing opBNB assets from the main chain back to the layer 2 network?","text":"

    Gas fees associated with withdrawing assets from the main chain back to the layer 2 network depend on the BNB chain\u2019s gas price at the time of withdrawal. These fees cover the cost of anchoring data on-chain and updating the network state.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#where-can-i-find-out-more-information-about-l2-gas-fees","title":"where can I find out more information about L2 gas fees?","text":"

    Prominent Layer 2 mainnet gas fees resource.

    To also check BNB Chain\u2019s Layer 1, BSC visit here.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#why-is-my-opbnb-transaction-rejected-or-pending","title":"Why is my opbnb transaction rejected or pending?","text":"

    There are several possible reasons why your transaction of opBNB may be rejected or pending. Here are some of the most common ones:

    To troubleshoot your transaction, you can do the following:

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#why-the-estimated-transaction-fee-is-zero-in-my-wallet","title":"Why the estimated transaction fee is zero in my wallet?","text":"

    It is because wallets are not well adapted to L2 networks. Wallets are designed for L1 networks, where the total transaction cost is calculated differently from L2 networks.

    For example, suppose you want to send some opBNB tokens on the opBNB network. When you use your wallet to approve the transaction, you will see that the estimated gas fee is 0BNB. This may seem like a great deal, but it is not the whole story.

    The gas fee you see in your wallet is based on the L2 part of the transaction, which is very low because it uses a batch processing technique to aggregate many transactions into one. The L2 part of the transaction consists of two components: the base fee and the priority fee. The base fee is a fixed amount that depends on the network congestion, and the priority fee is a variable amount that you can set to increase or decrease the speed of your transaction. For example, in our case, the base fee is 0.000000008 gwei and the priority fee is 0.00001 gwei, so the total L2 gas price is 0.000010008 gwei. The gas used is 21000, which is the standard amount for a transfer transaction. Therefore, the total L2 gas fee is 0.000010008 * 21000 = 0.210168 gwei, which is too small to be displayed in your wallet.

    However, this is not the only cost you have to pay for your transaction. There is also a layer 1 (L1) part of the transaction, which is the data cost. This is because every L2 transaction has to be recorded on the blockchain as data, and data storage on the blockchain is not free. The L1 part of the transaction depends on the size of the data and the L1 gas price at the time of submission. For example, in our case, the size of the data is 68 bytes and the L1 gas price is 249 gwei, so the total L1 gas fee is 68 * 249 = 16.932 gwei.

    Therefore, the actual cost of your transaction is the sum of the L2 and L1 parts, which is 0.210168 + 16.932 = 17.142168 gwei, or about 0.00001698 BNB, or about 0.003 USD at current prices. This is still very cheap compared to other blockchains, but it is not zero as your wallet shows.

    To verify this, you can check your transaction details on the opBNB explorer, where you will see both the L2 and L1 costs clearly displayed.

    We hope this helps you understand how opBNB works and why your wallet only shows the L2 cost.

    "},{"location":"bnb-opbnb/faq/gas-and-fees-faqs/#why-is-one-of-transactions-gas-fees-so-much-higher-than-the-rest","title":"Why is one of transaction\u2019s gas fees so much higher than the rest?","text":"

    A known issue that can cause irregularly high gas prices in opBNB transactions could be due to a high L1 gas price which is calculated by averaging block transaction gas prices using the formula: (Txn Fee = Gas Price * Gas + L1 Gas Price * L1 Gas Used * L1 Fee Scalar) This means that if there is an L1 block with an unusual high gas price, it will cause the gas price to be higher for a specific L2 block. This will be fixed going forward by introducing a static L1 gas price.

    "},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/","title":"opBNB Bridge - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/#what-is-the-status-of-the-integration-between-opbnb-and-optimisms-superchain","title":"What is the status of the integration between opBNB and Optimism\u2019s Superchain?","text":"

    opBNB is a project that aims to bring the benefits of L2 scaling and user-friendly UX to the BNB ecosystem. It will enable fast and cheap transactions on BNB L2, as well as smooth interoperability with Greenfield, a decentralized platform for building and running applications. Superchain is an innovative solution that leverages OP Stack to provide L2/L3 scaling and security for Ethereum. It allows users to access various L2 protocols with a single wallet and enjoy low fees and high throughput. opBNB is interested in collaborating with Superchain and integrating OP Stack into BNB Chain.

    "},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/#what-is-the-reason-for-the-discrepancy-in-the-estimated-cost-of-withdrawdeposit-transactions-between-the-opbnb-bridge-page-and-my-wallet","title":"What is the reason for the discrepancy in the estimated cost of withdraw/deposit transactions between the opBNB bridge page and my wallet?","text":"

    When you use the bridge to deposit or withdraw assets from opBNB, the bridge will estimate the gas cost for your transaction. This is done by simulating the execution of the transaction on the blockchain, without actually sending it or changing the state of the network. The simulation returns a number that indicates how much gas units the transaction would use if it was executed in the current network state.

    To get this number, the bridge uses a function called estimateGas, which implements a binary search algorithm between a lower and an upper bound of gas units. The lower bound is usually 21,000, which is the minimum gas required for a simple ether transfer. The upper bound is either specified by the user or derived from the block gas limit of the pending block. The function tries to execute the transaction with different gas values within this range until it finds the smallest gas value that does not cause an out-of-gas exception. This is the estimated gas usage of the transaction.

    For example: In this example, the bridge estimate of gas is around 0.0008 BNB, which is around $0.17.

    However, the wallet that you use to interact with the bridge may use a different method to calculate the estimated transaction cost. It may use the gas limit, which is the maximum amount of gas that you are willing to spend on the transaction. This is usually higher than the estimate given by the bridge.

    For example: The wallet estimate of the transaction is around 0.002 BNB, which is around $0.47.

    Once the transaction is executed on the chain, you can see the actual cost of the transaction in the opBNB explorer, which usually is similar to the estimate given by the bridge.

    "},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/#why-your-tokens-on-bsc-are-not-received-after-7-days-of-withdrawal-request","title":"Why your tokens on BSC are not received after 7 days of withdrawal request?","text":"

    You might have forgotten to sign the proof in the transaction history. This is a necessary step to initiate the 7 days challenge window. Without signing the proof, the bridge will not proceed with the challenge window and your withdrawal will be postponed.

    "},{"location":"bnb-opbnb/faq/opbnb-bridge-faqs/#why-do-i-need-to-sign-the-proof-to-start-the-7-days-challenge-window","title":"Why do I need to sign the proof to start the 7 days challenge window?","text":"

    When you withdraw tokens from opBNB to BSC, you need to provide a proof withdrawal to verify that your transaction on L2 is valid and consistent with the world state of L2. This is because L1 does not have access to the full world state of L2, only the data availability (DA) data and periodic snapshots of the world state from L2. The DA data is a compressed representation of the transactions on L2, which can be used to reconstruct the world state of L2 if needed. However, this process is expensive and time-consuming, so it is not done for every withdrawal. Instead, you need to submit a proof withdrawal, which is a cryptographic proof that your transaction on L2 matches the world state of L2 at a certain point in time. This way, you can ensure that your withdrawal is secure and accurate, and that no one can cheat or double-spend on L2.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/","title":"Protocol FAQs - opBNB FAQs","text":""},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-achieve-high-performance-and-cheap-gas-fees","title":"How does opBNB achieve high performance and cheap gas fees?","text":"

    opBNB testnet enhances the performance of the \u201cExecution Layer\u201d and the \u201cDerivation Layer\u201d of the OP Stack as highlighted in OP Stack landscape.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-do-you-expect-the-tps-of-the-opbnb","title":"How do you expect the TPS of the opBNB?","text":"

    The TPS of opBNB can be estimated to be around 4,761 transactions per second based on the calculations. This is significantly higher than Ethereum\u2019s current TPS and can enable more frequent daily transactions.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-impact-opbnb-can-bring-to-web3-games","title":"What impact opBNB can bring to web3 games?","text":"

    Performance is important for games because gamers expect a highly responsive experience. Any lag, delay or choppiness can hamper enjoyment and immersion in the game. For blockchain games, fast transaction speeds and throughput are crucial to enable a seamless user experience. Gamers expect in-game assets and currencies to be transferred instantly, so the underlying blockchain network must be high performance

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-is-the-difference-between-opbnb-and-other-optimism-based-layer-2-solution-like-base","title":"What is the difference between opBNB and other Optimism based layer 2 solution, like Base?","text":"

    opBNB is the first layer 2 optimistic rollup on BSC, and BSC layer 1 cost is much lower than ETH, so the cost of layer 2 on BSC will give application developers a more affordable solution. Another difference is the opBNB will include the performance optimization techniques that have been used in BSC to have a much better performance.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#we-already-have-the-zkbnb-as-a-scaling-solution-why-opbnb-is-needed","title":"We already have the zkBNB as a scaling solution, why opBNB is needed?","text":"

    zkBNB is not EVM-comptatible, which means it is more suitable for NFT and token transactions, not for generic dApps. opBNB`s programmability is to support applications that need more flexibility.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#is-opbnb-connected-to-the-superchain-or-is-unrelated-can-opbnb-be-considered-as-just-optimistic-rollups-on-the-bnb-smart-chain","title":"Is opBNB connected to the superchain or is unrelated? Can opBNB be considered as just optimistic rollups on the BNB Smart Chain?","text":"

    opBNB can be considered as just rollups on BSC, not superchain. Please check this blog for more details. We may expand opBNB to superchain or L3 in the future.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-are-the-differences-between-opbnb-the-op-stack-and-arbitrum-orbit-what-are-the-pros-and-cons-of-these-different-tech-stacks","title":"What are the differences between opBNB, the OP Stack, and Arbitrum Orbit? What are the pros and cons of these different tech stacks?","text":"

    Check this blog for more details on the differences between opBNB, the OP Stack, and Arbitrum Orbit.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#why-op-stack-is-used-for-the-implementation-of-opbnb-instead-of-zkevm","title":"Why OP Stack is used for the implementation of opBNB instead of zkEVM?","text":"

    OP Stack is a reliable and robust solution that has been verified through rigorous testing. OP Stack is designed with modularity in mind, allowing it to support multiple clients and different data access layers without affecting other parts of the code. opBNB leverages OP Stack as a solid foundation to explore various ways to lower the cost and enhance the user experience.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#are-transactions-nonce-order-enforced","title":"Are transactions nonce-order enforced?","text":"

    Yes, on opBNB transactions, nonce-order enforced.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-prevent-front-running-and-other-transaction-related-attacks","title":"How does opBNB prevent front-running and other transaction-related attacks?","text":"

    Front-running and other transaction-related attacks are challenges faced by many blockchain systems. opBNB uses mechanisms like transaction ordering and timestamping to mitigate these attacks. Aggregators are incentivized to order transactions fairly and not prioritize their own transactions, reducing the potential for front-running.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#can-i-run-my-own-validator-or-aggregator-node-on-the-opbnb-network","title":"Can I run my own validator or aggregator node on the opBNB network?","text":"

    The opBNB network currently does not support running validator or aggregator nodes by individual users. However, we are working on this feature and plan to release it in the future. Please keep following opBNB for the latest updates.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-handle-reentrancy-attacks-within-its-optimistic-rollup-framework","title":"How does opBNB handle reentrancy attacks within its optimistic rollup framework?","text":"

    opBNB employs a combination of security measures, including strict transaction ordering and careful state management, to prevent reentrancy attacks. By enforcing a controlled and deterministic execution order, reentrancy attacks are mitigated.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#whats-the-mechanism-for-preventing-long-range-attacks-on-the-opbnb-network","title":"What\u2019s the mechanism for preventing long-range attacks on the opBNB network?","text":"

    opBNB implements a checkpointing mechanism that anchors its state onto the main BNB chain. This helps prevent long-range attacks by ensuring that the latest valid state is preserved on-chain, making any attempted reorganizations infeasible.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-ensure-the-ordering-of-transactions-in-a-decentralized-manner-without-central-coordination","title":"How does opBNB ensure the ordering of transactions in a decentralized manner without central coordination?","text":"

    The opBNB team is responsible for operating the sequencer, which ensures the correct order of transactions on the network. The sequencer is a centralized component that provides a reliable and efficient service for the users.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-does-opbnb-handle-disputes-arising-from-cases-where-the-fraud-proof-itself-is-malicious-or-incorrect","title":"How does opBNB handle disputes arising from cases where the fraud proof itself is malicious or incorrect?","text":"

    opBNB employs a challenge mechanism to resolve disputes. If a malicious fraud proof is submitted, honest participants can submit counter-fraud proofs to correct the situation. The challenge period provides time for these proofs to be evaluated.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-is-the-challenge-period-on-opbnb","title":"What is the challenge period on opBNB?","text":"

    During the challenge period, any participant on the blockchain can raise challenges against the validity of the transactions or the execution results provided by the L2 sequencer. This mechanism is crucial for ensuring the integrity and correctness of the L2 execution.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-is-the-difference-between-validity-proof-and-fraud-proof","title":"What is the difference between validity proof and fraud proof?","text":"

    The validity proof is efficient at verifying, verifiers just need to check the \u201cproof\u201d once and confirm the correctness, but the disadvantage is that it is hard to generate the proof, both in algorithm and in efficiency. A popular validity proof solution is zero knowledge proof. On the other hand, the fraud proof is efficient at execution since it doesn\u2019t generate any proof at execution time, but the shorthand is that a specific time window must be established for participants to challenge the correctness of the L2 state, which will highly affect the finality of the L2 results.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#what-is-the-duration-of-the-challenge-period","title":"What is the duration of the challenge period?","text":"

    The challenge window is shorter on the testnet of opBNB, so you can test the withdrawal process faster. On the mainnet of opBNB, the challenge window will be 7 days long. 21. What are the penalties for dishonest sequencers? In case a sequencer is proven to be dishonest or provides incorrect execution results, penalties are applied. The sequencer\u2019s bond may be slashed as a form of punishment. Additionally, the state roots from the problematic transaction onwards will be erased and re-computed to ensure accuracy.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-to-check-if-a-smart-contract-is-verified-on-opbnb-using-an-api-get-request","title":"How to check if a smart contract is verified on opBNB using an API GET request?","text":"

    With the API key and smart contract address, you can retrieve the contract\u2019s verification status, source code & ABI.

    "},{"location":"bnb-opbnb/faq/protocol-faqs/#how-to-get-the-finalized-block-height-on-opbnb-and-why-is-it-always-hundreds-blocks-behind-the-latest","title":"How to get the finalized block height on opBNB and why is it always hundreds blocks behind the latest?","text":"

    The difference between latest and finalized by more than 200 blocks is expected. This is the concept in the OP design. The latest is defined as the latest unsafe block. The finalized means that the L2 block has been committed to L1 and the corresponding L1 block is finalized (by fast finality or natural finality).

    "},{"location":"bnb-opbnb/get-started/deposit-to-opbnb/","title":"Deposit BNB to opBNB - opBNB","text":""},{"location":"bnb-opbnb/get-started/deposit-to-opbnb/#deposit-bnbtbnb-to-opbnb","title":"Deposit BNB(tBNB) to opBNB","text":"

    Before building or deploying any applications on the opBNB network, you must first deposit BNB(tBNB) as your gas token from BNB Smart Chain to opBNB. You can do this using the opBNB bridge dApp(Testnet) or opBNB bridge dApp(Mainnet).

    Follow these steps to deposit tokens from BNB Smart Chain to opBNB:

    1. Make sure you have BNB(tBNB) tokens in your wallet on the BNB Smart Chain.
    2. In your wallet, switch your network to BNB Smart Chain. This is the Layer 1 network where your tokens currently are.
    3. Enter the amount of BNB(tBNB) you want to deposit to the opBNB network.
    4. Click \u201cDeposit\u201d to begin the transfer.
    5. Your wallet will prompt you to confirm the transaction. Click \u201cConfirm\u201d to sign it and pay the required gas fee.
    6. Once the transaction is processed, switch your network in your wallet to opBNB. The BNB amount you have deposited will appear in your wallet.
    7. You can now build, deploy, and interact with dApps on the opBNB network using the BNB(tBNB) you deposited. To withdraw tokens from opBNB back to BNB Smart Chain, simply go to the bridge, enter the amount to withdraw, and confirm the transaction. The bridge will transfer your tokens from the opBNB network back to the BNB Smart Chain testnet.

    "},{"location":"bnb-opbnb/get-started/deposit-to-opbnb/#opbnb-bridge-supported-tokens","title":"opBNB Bridge Supported Tokens","text":"

    The opBNB bridge supports you to transfer your assets from BSC to opBNB. The bridge supports most of the popular tokens, including BEP-20 tokens and wrapped bitcoin. If you want to test your applications that require these tokens, you can use the opBNB bridge to deposit and withdraw them in a simple and convenient way.

    The bridge page also provides a faucet link that allows you to claim these tokens from the faucet directly. To begin, simply click on the faucet link on the bridge page.

    "},{"location":"bnb-opbnb/get-started/network-info/","title":"Network Information - opBNB","text":""},{"location":"bnb-opbnb/get-started/network-info/#network-information","title":"Network Information","text":"Name Value Network Name opBNB Description The Layer 2 network of BNB Smart Chain. RPC Endpoint See here Chain ID 5611(Testnet), 204(Mainnet) Currency Symbol tBNB(Testnet) BNB(Mainnet) Block Explorer https://testnet.opbnbscan.com, https://opbnbscan.com, https://opbnb.bscscan.com/ Bridge https://opbnb-testnet-bridge.bnbchain.org, https://opbnb-bridge.bnbchain.org"},{"location":"bnb-opbnb/get-started/network-info/#rpc-endpoints","title":"RPC Endpoints","text":"

    You can use either public and private RPC endpoints to access opBNB.

    "},{"location":"bnb-opbnb/get-started/network-info/#public-testnet-rpc-endpointswss-is-supported","title":"Public Testnet RPC Endpoints(WSS is supported)","text":""},{"location":"bnb-opbnb/get-started/network-info/#public-mainnet-rpc-endpointswss-is-supported","title":"Public Mainnet RPC Endpoints(WSS is supported)","text":""},{"location":"bnb-opbnb/get-started/network-info/#private-opbnb-rpc-endpoints","title":"Private opBNB RPC Endpoints","text":"

    NodeReal supports the opBNB network, you can create your free opBNB RPC endpoints with your github or discord.

    To use the above private RPC endpoint, make sure to login to MegaNode service and create your private endpoints.

    "},{"location":"bnb-opbnb/get-started/wallet-configuration/","title":"Wallet Configuration - opBNB","text":""},{"location":"bnb-opbnb/get-started/wallet-configuration/#wallet-configuration","title":"Wallet configuration","text":"

    You can use any Ethereum or BSC wallet with opBNB. For instance, I will show you how to set up Metamask and Trustwallet for opBNB.

    To configure your wallet to work with opBNB, you will need to add both the BNB smart chain(Layer 1) and the opBNB network(Layer 2). Follow these steps:

    1. Add the BNB smart chain to your wallet. This is the Layer 1 blockchain that opBNB is built on top of.

    Testnet

    Mainnet

    Testnet

    Mainnet

    "},{"location":"bnb-opbnb/get-started/wallet-configuration/#references-how-to-configure-trustwallet-or-metamask","title":"References - How to configure Trustwallet or Metamask","text":"

    Trustwallet

    After you install the Trustwallet in your browser, you can go to settings->network.

    Select add custom network and enter the network information I mentioned above.

    Metamask

    After you install the metamask in your browser, you can go to settings -> networks -> add network page.

    Select add manual network and enter the network information.

    Depending on your location and preference, you can choose from a variety of RPC endpoints for BSC and opBNB. For more information about the endpoints and their features, please refer to the network information document that we have prepared for you. To ensure the best performance and user experience, you can test the latency of each endpoint before you configure it with your wallet.

    "},{"location":"bnb-opbnb/get-started/withdraw-from-opbnb/","title":"Withdrawal - opBNB","text":"

    To transfer your tokens from opBNB to BSC, you can use the opBNB bridge dApp(Testnet) or opBNB bridge dApp(Mainnet). Users who do not want to wait 7 days to claim their tokens can use a community bridge, but please note that community bridges may not be as secure as the official opBNB bridge.

    Note that the default option is the community bridge. To use the opBNB bridge, switch to the \u201cofficial bridge\u201d tab.

    "},{"location":"bnb-opbnb/get-started/withdraw-from-opbnb/#steps-of-withdrawal-through-official-bridge","title":"Steps of withdrawal through official bridge","text":"

    For users who choose the official opBNB bridge, you will need to wait for a challenge period of 7 days before you can claim your tokens on BSC. This challenge period is a security measure to prevent fraud and theft. The challenge period is necessary to ensure the security of the opBNB network and users. However, it can be inconvenient for users who need their tokens quickly. If you need your tokens immediately, you may want to consider using a community bridge instead. However, please be aware that community bridges may not be as secure as the official opBNB bridge. Do your research first.

    There are 2 steps after you submit your withdrawal request.

    1. Submit Proof: When you withdraw your tokens, they will be transferred from the opBNB network to the BSC network. After you submit the withdrawal request, your withdrawal status will change to Waiting for Proof, which indicates that the transaction is pending for the proof submission. You need to submit the proof manually.

    2. Claim Token: After you submit your proof, you need to wait until the transaction is ready to be collected after the challenge window, which is 7 days. The challenge window is a period of time during which anyone can challenge the validity of the transaction. If no one challenges the transaction, it will be finalized and you can collect your tokens on the BSC network.

    "},{"location":"bnb-opbnb/get-started/withdraw-from-opbnb/#third-party-bridges","title":"Third-party Bridges","text":"

    There are also third-party bridges with shorter withdrawal time.

    "},{"location":"bnb-smart-chain/","title":"BNB Smart Chain","text":"BNB Smart Chain

    BNB Smart Chain is a high-performance blockchain platform designed to enable the development of scalable and user-friendly decentralized applications (DApps), particularly in the decentralized finance (DeFi) space.

    Developers

    User guide to get started on BNB Smart Chain

    Staking

    BSC operates on a Proof-of-Staked-Authority (PoSA) blockchain

    Governance

    BSC is a community-oriented ecosystem, meticulously built upon the foundation of decentralized governance.

    Validator

    Validators secure the network based on the POSA consensus algorithm.

    Slashing

    Slashing is a component of on-chain governance that penalizes malicious or negative actions.

    BSC Ecosystem

    BSC ecosystem and developer tools

    Run a Node

    Run a BSC node

    MEV Builder

    Become a builder and create blocks and offering them to the validator

    JSON-RPC API

    Interacting with BSC requires sending requests to specific JSON-RPC API methods.

    "},{"location":"bnb-smart-chain/introduction/","title":"Introduction - BSC Develop","text":""},{"location":"bnb-smart-chain/introduction/#introduction","title":"Introduction","text":"

    BNB Smart Chain is an innovative solution to bring programmability and interoperability to BNB Beacon Chain. BNB Smart Chain relies on a system of 55 validators with Proof of Staked Authority (PoSA) consensus that can support short block time and lower fees. The most bonded validator candidates of staking will become validators and produce blocks. The double-sign detection, malicious vote detection and other slashing logic guarantee security, stability, and chain finality. Other than the 32 active validators, BSC will introduce more validators, e.g. another 23 inactive validators, into the validator set as backups, which will be called \u201cCandidates\u201d.

    Candidates will produce blocks and charge gas fees in BSC mainnet, but in a much less chance than the official validator set of 32 elected. The unavailable candidates will be slashed as well though in a smaller size. A decent motivation is expected to be maintained so that the candidate validators are willing to ensure the quality and help secure BSC.

    In an extreme case, if a majority of the active 32 validators get attacked and offline, Candidate Validators can report to BNB Beacon Chain about the stale blocking, resume it and eventually propose a re-election of the active validator set.

    The BNB Smart Chain also supports EVM-compatible smart contracts and protocols. Cross-chain transfer and other communication are possible due to native support of interoperability. The BNB Smart Chain will be:

    "},{"location":"bnb-smart-chain/introduction/#proof-of-staked-authority","title":"Proof of Staked Authority","text":"

    Although Proof-of-Work (PoW) has been recognized as a practical mechanism to implement a decentralized network, it is not friendly to the environment and also requires a large size of participants to maintain the security.

    Ethereum and some other blockchain networks, such as MATIC Bor, TOMOChain, GoChain, xDAI, do use Proof-of-Authority(PoA) or its variants in different scenarios, including both testnet and mainnet. PoA provides some defense to 51% attack, with improved efficiency and tolerance to certain levels of Byzantine players (malicious or hacked). It serves as an easy choice to pick as the fundamentals.

    Meanwhile, the PoA protocol is most criticized for being not as decentralized as PoW, as the validators, i.e. the nodes that take turns to produce blocks, have all the authorities and are prone to corruption and security attacks. Other blockchains, such as EOS and Lisk both, introduce different types of Delegated Proof of Stake (DPoS) to allow the token holders to vote and elect the validator set. It increases the decentralization and favors community governance.

    BSC here proposes to combine DPoS and PoA for consensus, so that:

    1. Blocks are produced by a limited set of validators
    2. Validators take turns to produce blocks in a PoA manner, similar to Ethereum\u2019s Clique consensus design
    3. Validator set are elected in and out based on a staking based governance

    Fast finalization can greatly improve user experience. The Fast Finality feature will be enabled upon the coming Plato upgrade. This will be a major advantage of BSC, and many dapps will benefit from it.

    The consensus protocol of BSC fulfills the following goals:

    1. Short Blocking time, 3 seconds on mainnet.
    2. It requires quite short time to confirm the finality of transactions, around 6s for mainnet after the coming Plato upgrade.
    3. There is no inflation of native token: BNB, the block reward is collected from transaction fees, and it will be paid in BNB.
    4. It is 100% compatible with Ethereum system.
    5. It allows modern proof-of-stake blockchain network governance.
    "},{"location":"bnb-smart-chain/introduction/#security","title":"Security","text":"

    Given there are more than \u00bd*N+1 validators are honest, PoA based networks usually work securely and properly. However, there are still cases where certain amount Byzantine validators may still manage to attack the network, e.g. through the Clone Attack. BSC does introduce Slashing logic to penalize Byzantine validators for double signing or inavailability. This Slashing logic will expose the malicious validators in a very short time and make the \u201cClone Attack\u201d very hard or extremely non-beneficial to execute.

    "},{"location":"bnb-smart-chain/introduction/#fast-finality","title":"Fast Finality","text":"

    Finality is critical for blockchain security, once the block is finalized, it wouldn\u2019t be reverted anymore. The fast finality feature is very useful, the users can make sure they get the accurate information from the latest finalized block, then they can decide what to do next instantly. More details of design, please to refer BEP-126

    Before the coming Plato upgrade,to secure as much as BC, BSC users are encouraged to wait until receiving blocks sealed by more than \u2154*N+1 different validators. In that way, the BSC can be trusted at a similar security level to BC and can tolerate less than \u2153*N Byzantine validators.With 21 validators, if the block time is 3 seconds, the \u2154*N+1 different validator seals will need a time period of (\u2154*21+1)*3 = 45 seconds. Any critical applications for BSC may have to wait for \u2154*N+1 to ensure a relatively secure finality. With above enhancement by slashing mechanism, \u00bd*N+1 or even fewer blocks are enough as confirmation for most transactions.

    After the coming Plato upgrade, the feature Fast Finality will be enabled. The chain will be finalized within two blocks if \u2154*N or more validators vote normally, otherwise the chain has a fixed number of blocks to reach probabilistic finality as before.

    "},{"location":"bnb-smart-chain/introduction/#reward","title":"Reward","text":"

    All the BSC validators in the current validator set will be rewarded with transaction fees in BNB. As BNB is not an inflationary token, there will be no mining rewards as what Bitcoin and Ethereum network generate, and the gas fee is the major reward for validators. After the coming Plato upgrade, part of the fees collected will be used as reward for finality voting. As BNB is also utility tokens with other use cases, delegators and validators will still enjoy other benefits of holding BNB.

    The reward for validators is the fees collected from transactions in each block. Validators can decide how much to give back to the delegators who stake their BNB to them, in order to attract more staking. Every validator will take turns to produce the blocks in the same probability (if they stick to 100% liveness), thus, in the long run, all the stable validators may get a similar size of the reward. Meanwhile, the stakes on each validator may be different, so this brings a counter-intuitive situation that more users trust and delegate to one validator, they potentially get less reward. So rational delegators will tend to delegate to the one with fewer stakes as long as the validator is still trustful (insecure validator may bring slashable risk). In the end, the stakes on all the validators will have less variation. This will actually prevent the stake concentration and \u201cwinner wins forever\u201d problem seen on some other networks.

    "},{"location":"bnb-smart-chain/introduction/#token-economy","title":"Token Economy","text":"

    BC and BSC share the same token universe for BNB and BEP2 tokens. This defines:

    1. The same token can circulate on both networks, and flow between them bi-directionally via a cross-chain communication mechanism.
    2. The total circulation of the same token should be managed across the two networks, i.e. the total effective supply of a token should be the sum of the token\u2019s total effective supply on both BSC and BC.
    3. The tokens can be initially created on BSC in a similar format as ERC20 token standard, or on BC as a BEP2, then created on the other. There are native ways on both networks to link the two and secure the total supply of the token.
    "},{"location":"bnb-smart-chain/introduction/#staking-and-governance","title":"Staking and Governance","text":"

    Proof of Staked Authority brings in decentralization and community involvement. Its core logic can be summarized as the below. You may see similar ideas from other networks, especially Cosmos and EOS.

    1. Token holders, including the validators, can put their tokens \u201cbonded\u201d into the stake. Token holders can delegate their tokens onto any validator or validator candidate, to expect it can become an actual validator, and later they can choose a different validator or candidate to re-delegate their tokens.
    2. All validator candidates will be ranked by the number of bonded tokens on them, and the top ones will become the real validators.
    3. Validators can share (part of) their blocking reward with their delegators.
    4. Validators can suffer from \u201cSlashing\u201d, a punishment for their bad behaviors, such as double sign and/or instability.
    5. There is an \u201cunbonding period\u201d for validators and delegators so that the system makes sure the tokens remain bonded when bad behaviors are caught, the responsible will get slashed during this period.
    "},{"location":"bnb-smart-chain/overview/","title":"Overview - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/overview/#bnb-smart-chain-high-performance-defi-hub","title":"BNB Smart Chain - High Performance DeFi Hub","text":"

    BNB Smart Chain (BSC) is a high-performance blockchain network. Officially launched on September 1, 2020, BSC is designed to enhance the functionality of the BNB Chain and facilitate the development and interaction of decentralized applications (DApps), decentralized finance (DeFi) platforms, and other blockchain-based innovations.

    "},{"location":"bnb-smart-chain/overview/#key-features-and-advantages","title":"Key Features and Advantages","text":"
    1. Ethereum Virtual Machine (EVM) Compatibility: BSC is fully compatible with the Ethereum Virtual Machine (EVM), enabling developers to port their Ethereum-based DApps and DeFi projects to BSC with minimal modifications. This compatibility extends to the use of popular Ethereum tools and applications, such as MetaMask, Truffle, and Remix.

    2. Low Transaction Fees and Fast Block Times: One of BSC\u2019s primary advantages is its low transaction fees. As of early 2024, the average transaction fee on BSC is around $0.10, significantly lower compared to Ethereum\u2019s average fee of \\(10-\\)20 during periods of high network congestion. Additionally, BSC block time of approximately is 3 seconds, ensuring rapid transaction confirmations and an overall smoother user experience.

    3. Robust Ecosystem and Growing Adoption: Since its inception, BSC has seen rapid growth in its ecosystem. By May 2024, BSC supports over 1,500 DApps, with popular platforms such as PancakeSwap, Venus, and BakerySwap leading the charge. The total value locked (TVL) in BSC-based DeFi protocols exceeds $20 billion, reflecting its substantial market adoption and user trust.

    "},{"location":"bnb-smart-chain/overview/#role-of-bnb","title":"Role of BNB","text":"

    BNB is the native utility token of both BNB Chain and BNB Smart Chain. Within the BSC ecosystem, BNB is used for various purposes:

    "},{"location":"bnb-smart-chain/overview/#future-prospects","title":"Future Prospects","text":"

    BNB Smart Chain is positioned as a significant player in the blockchain space, particularly in the realm of DeFi and DApps. With its emphasis on high performance, affordability, and interoperability, BSC aims to address some of the most pressing challenges facing blockchain technology today. As the blockchain landscape continues to evolve, BSC\u2019s strategic innovations and growing community are likely to drive further advancements and widespread adoption.

    "},{"location":"bnb-smart-chain/developers/faucet/","title":"Faucet - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/faucet/#claim-test-tbnb-tokens","title":"Claim test tBNB Tokens","text":""},{"location":"bnb-smart-chain/developers/faucet/#claim-tbnb-from-online-faucet","title":"Claim tBNB from Online Faucet","text":"

    To get some tBNB of BSC testnet for testing purposes, you can use the online faucet to claim your tokens.

    1. Copy your wallet address and paste the address into the textbox

    2. Select the tokens you need to claim. Major pegged tokens like BUSD, USDT, and others are supported.

    3. Please note if your wallet balance is larger than 1 tBNB, you can not get new tBNB from the Discord bot faucet.*

    "},{"location":"bnb-smart-chain/developers/faucet/#claim-tbnb-from-discord","title":"Claim tBNB from Discord","text":"
    1. Visit the BNB Chain Discord faucet channel
    2. Type /faucet {your receiver account} and sent.
    3. You will receive 0.3 tBNB in few seconds.

    You can only claim once in 24 hours.

    "},{"location":"bnb-smart-chain/developers/faucet/#claim-tbnb-from-third-party-faucets","title":"Claim tBNB from Third-party Faucets","text":"

    You can also claim tBNB from the following third-party faucets

    1. https://faucet.quicknode.com/binance-smart-chain/bnb-testnet

    2. https://faucet.chainstack.com/bnb-testnet-faucet

    3. https://thirdweb.com/opbnb-testnet

    "},{"location":"bnb-smart-chain/developers/quick-guide/","title":"Quick Guide - BNB Smart Chain (BSC)","text":"

    If you are a developer looking to build applications on the BNB Smart Chain (BSC), this document provides all the essential information you need.

    "},{"location":"bnb-smart-chain/developers/quick-guide/#getting-started","title":"Getting Started","text":"

    BNB Smart Chain (BSC) is a high-performance blockchain network.

    Since BSC is EVM-compatible, your existing Ethereum smart contract skills will seamlessly transfer to BSC.

    "},{"location":"bnb-smart-chain/developers/quick-guide/#connecting","title":"Connecting","text":"

    Here are some resources to help you get connected to the BSC network:

    "},{"location":"bnb-smart-chain/developers/quick-guide/#get-tokens","title":"Get Tokens","text":"

    BNB is the native utility token of BNB Smart Chain and is used to pay transaction fees. For the testnet, you can use the faucet to obtain test tokens on BSC.

    For the mainnet, you can withdraw tokens directly from a centralized exchange (CEX) which supports BSC network(e.g. Binance).

    "},{"location":"bnb-smart-chain/developers/quick-guide/#json-rpc-api","title":"JSON-RPC API","text":"

    Interacting with BSC requires sending requests to specific JSON-RPC API methods. BSC\u2019s APIs are compatible with Geth. - JSON-RPC API

    "},{"location":"bnb-smart-chain/developers/quick-guide/#developer-tools","title":"Developer Tools","text":"

    For more tools and details, you can refer to BSC Dev Tools.

    "},{"location":"bnb-smart-chain/developers/rpc/","title":"RPC - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/rpc/#json-rpc-endpoint","title":"JSON-RPC Endpoint","text":"

    JSON-RPC endpoints refers to the network location where a program could transfer its RPC requests to access server data. Once you connect a decentralized application to an RPC endpoint, you can access the functionalities of different operations, which could enable real-time usage of blockchain data. BNB Chain provides several RPC endpoints for connectinto both its Minent and Testnet. In this section, we list the JSON-RPC endpoints that can be used for connecting to BNB Smart Chain.

    "},{"location":"bnb-smart-chain/developers/rpc/#one-click-adding-bsc-network","title":"One-click adding BSC network","text":"

    Visit the ChainList and connect to your wallet, it will add alive RPC endpoints.

    "},{"location":"bnb-smart-chain/developers/rpc/#rpc-endpoints-for-bnb-smart-chain","title":"RPC Endpoints for BNB Smart Chain","text":"

    The rate limit of BSC endpoint on Testnet and Mainnet is 10K/5min.

    eth_getLogs is disabled on below Mainnet endpoints, please use 3rd party endpoints from here. If you need to pull logs frequently, we recommend using WebSockets to push new logs to you when they are available.

    "},{"location":"bnb-smart-chain/developers/rpc/#bsc-mainnet-chainid-0x38-56-in-decimal","title":"BSC Mainnet (ChainID 0x38, 56 in decimal)","text":"

    You could find more endpoints from here.

    "},{"location":"bnb-smart-chain/developers/rpc/#bsc-testnet-chainid-0x61-97-in-decimal","title":"BSC Testnet (ChainID 0x61, 97 in decimal)","text":""},{"location":"bnb-smart-chain/developers/rpc/#rpc-providers","title":"RPC Providers","text":""},{"location":"bnb-smart-chain/developers/rpc/#starting-http-json-rpc","title":"Starting HTTP JSON-RPC","text":"

    You can start the HTTP JSON-RPC with the \u2013http flag

    ## mainnet\ngeth attach https://bsc-dataseed.bnbchain.org\n\n## testnet\ngeth attach https://bsc-testnet-dataseed.bnbchain.org\n
    "},{"location":"bnb-smart-chain/developers/rpc/#json-rpc-methods","title":"JSON-RPC methods","text":"

    Please refer to this wiki page or use Postman: https://documenter.getpostman.com/view/4117254/ethereum-json-rpc/RVu7CT5J?version=latest

    "},{"location":"bnb-smart-chain/developers/wallet-configuration/","title":"Wallet Configuration - BNB Smart Chain (BSC)","text":""},{"location":"bnb-smart-chain/developers/wallet-configuration/#wallet-configuration","title":"Wallet configuration","text":"

    You can use any Ethereum wallet with BSC. For instance, I will show you how to set up Metamask and Trustwallet for BSC.

    Testnet

    Mainnet

    "},{"location":"bnb-smart-chain/developers/wallet-configuration/#references-how-to-configure-trustwallet-or-metamask","title":"References - How to configure Trustwallet or Metamask","text":"

    Trustwallet

    After you install the Trustwallet in your browser, you can go to settings->network.

    Select add custom network and enter the network information I mentioned above.

    Metamask

    After you install the metamask in your browser, you can go to settings -> networks -> add network page.

    Select add manual network and enter the network information.

    Depending on your location and preference, you can choose from a variety of RPC endpoints for BSC. For more information about the endpoints and their features, please refer to the network information document that we have prepared for you. To ensure the best performance and user experience, you can test the latency of each endpoint before you configure it with your wallet.

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/","title":"Archive Node - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#how-to-run-an-archive-node-on-bnb-smart-chain","title":"How to Run an Archive Node on BNB Smart Chain","text":""},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#what-is-an-archive-node","title":"What is an archive node?","text":"

    Simply speaking, an archive node is a full node running with an additional special option, --gcmode archive. It stores all the historical data of the blockchain starting from the genesis block. As compared to a typical full node that just holds all the state change data for some latest blocks, an archive node always stores them for each block.

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#why-is-an-archive-node-important","title":"Why is an archive node important?","text":"

    Developers are limited to querying the limited recent blocks to check the balance of an address and the state of a smart contract with a full node. It is hard to get all what they want as the blockchain is moving forward at the same time, while they can query any block at a specific point in time with an archive node. Archive nodes are used by various applications on the blockchain for challenging use cases, including but not limited to the followings:

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#suggested-requirements","title":"Suggested Requirements","text":"

    Running an archive node will take a high cost as it includes all the block and state change data. First of all it needs the disk with sufficient capacity; besides this, the CPU and disk performance should be good enough to catch up with the latest block height. You can refer to the suggested hardware requirements.

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#how-to-run-an-archive-node-for-bsc-mainnet","title":"How to run an archive node for BSC mainnet?","text":""},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#run-with-an-erigon-client","title":"Run with an Erigon client","text":"

    Erigon has supported BSC mainnet. You can also refer to Free public BNB Smart Chain Archive Snapshot for the guide to run a BSC archive node with an Erigon client. The owner has switched to using an Erigon client for a BSC archive node recently. You can download the archive snapshot which is a tarball from aws s3. The s3 path is \u201cs3://public-blockchain-snapshots/bsc/erigon-latest.tar.zstd\u201d. This path is public, but is configured as requester-pays. Also this means you\u2019ll need an AWS account in order to download it.

    aws s3 cp --request-payer=requester  \"s3://public-blockchain-snapshots/bsc/erigon-latest.tar.zstd\"   local_data_dir\n\ntar --use-compress-program=unzstd -xvf erigon-latest.tar.zstd\n
    ./erigon --chain=bsc --datadir  local_data_dir\n

    The known Issue with an Erigon client is that it does not really keep up with the latest blocks as mentioned in the Github. If you want to keep up with the latest blocks it is suggested to run a BSC archive node with high performance disk such as NVME, or run a BSC full node with a Geth client at the same time which means you need one proxy that will ask Erigon if it has the block height and if not forward it to the Geth client.

    "},{"location":"bnb-smart-chain/developers/node_operators/archive_node/#run-with-a-reth-client","title":"Run with a Reth client","text":"

    Reth now supports the BSC network and demonstrates superior performance compared to Geth and Erigon in recent benchmark tests. You can utilize reth to operate an archive node; for more information, refer to Reth Node.

    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/","title":"Boot Node - BSC Develop","text":"

    Through the maintenance release v1.2.12 4, Boot Nodes were introduced on the BSC mainnet. BSC Boot Nodes are similar to Ethereum Boot Nodes, refer here for more details. The main benefit of Boot Nodes is that it would be easier for user to connect to the BSC network. Users would no longer need to setup the StaticNodes in config.toml, just leave it empty and make sure delete the BootstrapNodes field in config.toml.

    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#impact-to-users","title":"Impact To Users","text":""},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#static-nodes-could-be-stopped","title":"Static Nodes Could Be Stopped","text":"

    Previously, BSC provides a list of StaticNodes for users to connect to the network, they are working as a full node and also serving the P2P discovery protocol. New BSC nodes connect to the BSC network through these StaticNodes. It works, but is not quite stable, since they could have very heavy workload.

    These static nodes could be stopped and replaced by Boot Nodes in the future. And the StaticNodes list provided before could no longer be available. Like the list provided in v1.2.11 5:

    StaticNodes = [\n\"enode://fe0bb07eae29e8cfaa5bb15b0db8c386a45b7da2c94e1dabd7ca58b6327eee0c27bdcea4f08db19ea07b9a1391e5496a28c675c6eee578154edae4fa44640c5d@54.228.2.74:30311\",\n\"enode://c307b4cddec0aea2188eafddedb0a076b9289402c63217b4c81eb7f34761c7cfaf6b075e93d7357169e226ff1bb4aa3bd71869b4c76cf261e2991005ddb4d4aa@3.81.81.182:30311\",\n\"enode://84a76ad1fab6164cbb00179dd07c96755141ffb75d5d387f45295e6ecfcc9e12a720f1f3dca8318449eeff768d13e9d49a414d2b522d1bcf2919aebf4852ab46@44.198.58.179:30311\",\n\"enode://41d57b0f00d83016e1bb4eccff0f3034aa49345301b7be96c6bb23a0a852b9b87b9ed11827c188ad409019fb0e578917d722f318665f198340b8a15ae8beff36@34.252.87.229:30311\",\n\"enode://accbc0a5af0af03e1ec3b5e80544bdceea48011a6928cd82d2c1a9c38b65fd48ec970ba17bd8c0b0ec21a28faec9efe1d1ce55134784b9207146e2f62d8932ba@54.162.32.1:30311\",\n\"enode://e333532e47a14dba7603c9ab0598e68be2c0822200855844edd45f50bfba481451ca5ee5247dbca2b54fe522e74a658edc15c8eed917360e1a289b3ab78ecf4c@3.250.36.7:30311\",\n\"enode://9f005be9111a6152884fd575abb55bddb1e7f726510c96cddde57a9bba84ffa4952a89d7632c9c9dd50d3750f83966a73a0f7ed793f253a3691b84a687b29b6c@3.88.177.211:30311\",\n\"enode://5451251a9902e658154456ea98ebdd93313e54496ce0a6ca2242fe4db882940d78d758c85a36485af54b0841270f2bdbff64d66c45976f3ed1dd912f7649c831@3.236.189.129:30311\",\n\"enode://a232f92d1e76447b93306ece2f6a55ac70ca4633fae0938d71a100757eaf8526e6bbf720aa70cba1e6d186be17291ad1ee851a35596ec6caa2fdf135ce4b6b68@107.20.124.16:30311\",\n\"enode://62c516645635f0389b4c851bfc4545720fac0607de74942e4ea7e923f4fa2ac0c438c146e2f0721c8ce06dca4e7f30f5c0136569d9f4b6a827c62b980fd53272@52.215.57.20:30311\",\n\"enode://c014bbf48209cdf8ca6d3bf3ff5cf2fade45104283dcfc079df6c64e0f4b65e4afe28040fa1731a0732bd9cbb90786cf78f0174b5de7bd5b303088e80d8e6a83@54.74.101.143:30311\",\n\"enode://710ed272e03b92c803cd165e5fa071da015815d312f17d107a43ad3b12b0f05c830c58ced2df7547294f5365fe76cdcf1a58f923ee5612d247a6d5b80cfe16a8@34.245.31.55:30311\",\n\"enode://768af449287561c0f17bb5dc5d98a1c6a4b1798cb41159bd0a7bfebdc179e39ad8076d7292caa9344eecb94a5f7499e632c29cc4edbdf2e8ada3f7c8c7b2a64b@3.95.173.72:30311\",\n\"enode://8428650e034341479d0ca3142bcd412f400ba47454bb7caeb88cfeb9bb60c21e45153eddf3e334d5d94ae67609ec2ac44816b346a2b3216d94a7c095883141e3@54.195.188.155:30311\"\n]\n
    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#to-join-the-network-with-bootnodes","title":"To Join The Network With BootNodes","text":"
    ...\n[Node.P2P]\nMaxPeers = 200\nNoDiscovery = false\nBootstrapNodes = [\n\"enode://433c8bfdf53a3e2268ccb1b829e47f629793291cbddf0c76ae626da802f90532251fc558e2e0d10d6725e759088439bf1cd4714716b03a259a35d4b2e4acfa7f@52.69.102.73:30311\",\n\"enode://571bee8fb902a625942f10a770ccf727ae2ba1bab2a2b64e121594a99c9437317f6166a395670a00b7d93647eacafe598b6bbcef15b40b6d1a10243865a3e80f@35.73.84.120:30311\",\n\"enode://fac42fb0ba082b7d1eebded216db42161163d42e4f52c9e47716946d64468a62da4ba0b1cac0df5e8bf1e5284861d757339751c33d51dfef318be5168803d0b5@18.203.152.54:30311\",\n\"enode://3063d1c9e1b824cfbb7c7b6abafa34faec6bb4e7e06941d218d760acdd7963b274278c5c3e63914bd6d1b58504c59ec5522c56f883baceb8538674b92da48a96@34.250.32.100:30311\",\n\"enode://ad78c64a4ade83692488aa42e4c94084516e555d3f340d9802c2bf106a3df8868bc46eae083d2de4018f40e8d9a9952c32a0943cd68855a9bc9fd07aac982a6d@34.204.214.24:30311\",\n\"enode://5db798deb67df75d073f8e2953dad283148133acb520625ea804c9c4ad09a35f13592a762d8f89056248f3889f6dcc33490c145774ea4ff2966982294909b37a@107.20.191.97:30311\"\n]\nStaticNodes = []\nListenAddr = \":30311\"\n...\n
    ...\n[Node.P2P]\nMaxPeers = 200\nNoDiscovery = false\nStaticNodes = []\nListenAddr = \":30311\"\n..\n
    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#to-run-a-boot-node","title":"To Run A Boot Node","text":"

    Boot nodes are super-lightweight nodes, they can be ran by a very cheap device, like: 2 cores, 2GB memory, 20GB disk. \\ If you want to support the BSC ecosystem by providing new boot nodes, you can follow this guide to do it.

    "},{"location":"bnb-smart-chain/developers/node_operators/boot_node/#help","title":"Help","text":"

    Since boot nodes have been introduced recently, if you get any problem in using it, please let us know. You may just create new issue in BSC GitHub repo.

    "},{"location":"bnb-smart-chain/developers/node_operators/docker/","title":"Run BSC Nodes using Docker - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#how-to-run-a-fullnode-using-bsc-docker-image","title":"How to Run A Fullnode Using BSC Docker Image","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#resources","title":"Resources","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#supported-platforms","title":"Supported Platforms","text":"

    We support running a BSC docker image on Mac OS X, Linux, and Windows.

    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#steps-to-run-a-fullnode-in-docker","title":"Steps to Run a Fullnode in Docker","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#install-docker","title":"Install Docker","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#post-install","title":"Post install:","text":"

    Start docker during boot up:

    systemctl enable docker.service\nsystemctl enable containerd.service\n
    Add user \u201cubuntu\u201d to group docker so the user has privileges to run docker commands:
    usermod -aG docker ubuntu\n
    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#pull-bsc-node-image","title":"Pull BSC Node Image","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#download-bsc-node-config-files","title":"Download BSC Node Config Files","text":"

    Download genesis.json and config.toml by:

    Mainnet

    wget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep mainnet |cut -d\\\" -f4)\nunzip mainnet.zip\n
    Testnet
    wget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep testnet |cut -d\\\" -f4)\nunzip testnet.zip\n
    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#running-docker-container","title":"Running Docker Container","text":"
    1. Dockers Variables and Config file Location

    Important Environment Variables to note:

    $BSC_HOME = /bsc\n$DATA_DIR = /data\n
    File location:

    Essentially we need to bind mount two directories:

    Mount Local Docker Blockchain data data/node /bsc/node Config files config /bsc/config
    1. Download data on local host Download latest chaindata snapshot from here. Follow the guide to structure your files.

    2. Start container

    You can also use ETHEREUM OPTIONS to overwrite settings in the configuration file:

    docker run -v $(pwd)/config:/bsc/config -v $(pwd)/data/node:/bsc/node -p 8575:8575 --rm --name bsc -it ghcr.io/bnb-chain/bsc:1.1.18_hr --http.addr 0.0.0.0 --http.port 8575 --http.vhosts '*' --verbosity 5\n
    * -p 8575:8575: This will map port 8575 from host to container, so it exposes 8575 on host node. * \u2013http \u2013http.addr 0.0.0.0: Extra Geth flags to enable RPC and listen on all network interfaces of the container.

    NOTE: port 8575 is the default port for the RPC service on TESTNET. If you are using mainnet the default port is 8545.

    1. Start Geth console
      geth attach http://localhost:8575\n
    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#how-to-access-the-container","title":"How to access the container","text":"

    Execute bash (shell/terminal) on the container named bsc:

    docker exec -it bsc bash\n
    Once logged in you can perform regular tasks you would do on a node without docker."},{"location":"bnb-smart-chain/developers/node_operators/docker/#how-to-check-node-running-status","title":"How to Check Node Running Status","text":""},{"location":"bnb-smart-chain/developers/node_operators/docker/#check-synchronization","title":"Check Synchronization","text":"

    Start Geth Console:

    geth attach ipc:node/geth.ipc\n
    Once started, run:
    >eth.syncing\n
    "},{"location":"bnb-smart-chain/developers/node_operators/docker/#check-geth-logs","title":"Check Geth Logs","text":"
    tail -f node/bsc.log\n
    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/","title":"Fast Node - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#fast-node-on-bnb-smart-chain","title":"Fast Node on BNB Smart Chain","text":""},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#note","title":"Note","text":"

    Fast Node does not generate Trie Data when syncing. Once the Fast Node is running, there is no way to switch back to Full Node. Need to re-download snapshot data to restore it to Full Node.

    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#fast-node-functions","title":"Fast Node Functions","text":""},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#steps-to-run-a-fast-node","title":"Steps to Run a Fast Node","text":""},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#download-the-pre-build-binaries-from-release-page-or-follow-the-instructions-below","title":"Download the pre-build binaries from release page or follow the instructions below:","text":"
    # Linux\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_linux |cut -d\\\" -f4)\nmv geth_linux geth\nchmod -v u+x geth\n\n# MacOS\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_mac |cut -d\\\" -f4)\nmv geth_mac geth\nchmod -v u+x geth\n
    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#download-the-config-files","title":"Download the config files","text":"

    Download genesis.json and config.toml by:

    wget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep mainnet |cut -d\\\" -f4)\nunzip mainnet.zip\n
    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#download-snapshot","title":"Download snapshot","text":"

    Download latest chaindata snapshot from here. Follow the guide to structure your files.

    :::note Your \u2013datadir flag should point to the extracted chaindata folder path :::

    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#prune-all-trie-data","title":"Prune all trie data","text":"

    Fast node does not need trie data anymore, prune the trie data by the following command.

    ./geth snapshot insecure-prune-all --datadir ./node  ./genesis.json\n
    "},{"location":"bnb-smart-chain/developers/node_operators/fast_node/#start-fast-node-without-snapshot-verification","title":"Start Fast Node Without Snapshot Verification","text":"

    You can start Fast Node without snapshot verification by verify nodes.

    ## start a fast node\n./geth --tries-verify-mode none --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n

    Or start Fast Node With Snapshot Verification 1. Add verifyNodes peers in config.toml.

    [Node.P2P]\nMaxPeers = 1350\nNoDiscovery = false\nBootstrapNodes = [\"enode://...\", \"enode://...\", ...]\nVerifyNodes = [\"enode://...\", \"enode://...\", ...]\nStaticNodes = [\"enode://...\", \"enode://...\", ...]\nListenAddr = \":30311\"\nEnableMsgEvents = false\n
    1. Start your fast node with snapshot verification by verify nodes.
    ## start a fast node\n./geth --tries-verify-mode full --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n
    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/","title":"Full Node - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/full_node/#how-to-run-a-fullnode-on-bnb-smart-chain","title":"How to Run A Fullnode on BNB Smart Chain","text":""},{"location":"bnb-smart-chain/developers/node_operators/full_node/#fullnodes-functions","title":"Fullnodes Functions","text":""},{"location":"bnb-smart-chain/developers/node_operators/full_node/#supported-platforms","title":"Supported Platforms","text":"

    We support running a full node on Mac OS X, Linux, and Windows.

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#steps-to-run-a-fullnode","title":"Steps to Run a Fullnode","text":""},{"location":"bnb-smart-chain/developers/node_operators/full_node/#sync-from-snapshot-recommended","title":"Sync From Snapshot (Recommended)","text":"
    1. Download the pre-build binaries from the release page or follow the instructions below

      # Linux\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_linux |cut -d\\\" -f4)\nmv geth_linux geth\nchmod -v u+x geth\n\n# MacOS\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_mac |cut -d\\\" -f4)\nmv geth_mac geth\nchmod -v u+x geth\n
    2. Download the config files

      Download genesis.json and config.toml by:

      # mainnet\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep mainnet |cut -d\\\" -f4)\nunzip mainnet.zip\n\n# testnet\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep testnet |cut -d\\\" -f4)\nunzip testnet.zip\n
    3. Download snapshot Download latest chaindata snapshot from here. Follow the guide to structure your files.

      Tip

      Your \u2013datadir flag should point to the folder where the extracted snapshot data is. In our case, we created a new folder named node, and we moved the extracted snapshot data to this folder.

      mv server/data-seed/geth/chaindata node/geth/chaindata\nmv server/data-seed/geth/chaindata node/geth/triecache\n
    4. Start a full node

      ./geth --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n

      Note

      Make sure you use the version of geth you downloaded with wget above, and not your local installation of geth, which might be the wrong version. For all geth nodes, DO NOT use -pipecommit flag

      Tip

      It is recommended to run a fast node, which is a full node with the flag --tries-verify-mode none set if you want high performance and care little about state consistency. Check here for full details on running a fast node. It will run with Hash-Base Storage Scheme by default

      ./geth --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0 --tries-verify-mode none\n

      It will run with Path-Base Storage Scheme. It will enable inline state prune, keeping the latest 90000 blocks\u2019 history state by default.

      ./geth --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0 --tries-verify-mode none --state.scheme path\n
    5. Monitor node status

      You can monitor the log from ./node/bsc.log by default. When your node has started syncing, you should be able to see the following output:

      t=2022-09-08T13:00:27+0000 lvl=info msg=\"Imported new chain segment\"             blocks=1    txs=177   mgas=17.317   elapsed=31.131ms    mgasps=556.259  number=21,153,429 hash=0x42e6b54ba7106387f0650defc62c9ace3160b427702dab7bd1c5abb83a32d8db dirty=\"0.00 B\"\nt=2022-09-08T13:00:29+0000 lvl=info msg=\"Imported new chain segment\"             blocks=1    txs=251   mgas=39.638   elapsed=68.827ms    mgasps=575.900  number=21,153,430 hash=0xa3397b273b31b013e43487689782f20c03f47525b4cd4107c1715af45a88796e dirty=\"0.00 B\"\nt=2022-09-08T13:00:33+0000 lvl=info msg=\"Imported new chain segment\"             blocks=1    txs=197   mgas=19.364   elapsed=34.663ms    mgasps=558.632  number=21,153,431 hash=0x0c7872b698f28cb5c36a8a3e1e315b1d31bda6109b15467a9735a12380e2ad14 dirty=\"0.00 B\"\n
    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#sync-from-genesis-block-not-recommended","title":"Sync From Genesis Block (Not Recommended)","text":"

    Caution

    It is recommended to use HBSS with level DB for archive node, PBSS for archive node is not supported yet.

    Note

    To sync from genesis block, you would need a more powerful hardware. Server should at least have 40k IOPS and be at least an i3/i3en series server.

    ## start a full node\n./geth --config ./config.toml --datadir ./node  --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n
    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#sync-mode","title":"Sync Mode","text":"

    There are two sync modes for running a full node: snap and full which can be specified by flag \u2013syncmode.

    The snap sync mode is used for initial sync, which will download the latest states rather than execute the blocks from the genesis. When the initial sync is done, it will switch to full sync automatically.

    The full sync mode can also be used to do initial sync, which will execute all the blocks since genesis. But it is not recommended, since the amount of historical data is too large. Instead, you can download a snapshot from the official repo and start full sync from the snapshot.

    If the flag \u2013syncmode is not provided, the default sync mode will depend on the state of the data folder. It will be snap mode if you sync from genesis or full mode if you start from a snapshot.

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#full-sync-with-greenfield-peer-optional","title":"Full Sync with Greenfield Peer (Optional)","text":"

    Opting for full sync mode means your node will only need block headers and bodies from other network peers. To expedite this process, consider utilizing the Greenfield Peer.

    This data seed, offered by Greenfield, allows for a more efficient synchronization. Configure your BSC node to connect with the Greenfield Light Peer by modifying your configuration file settings. For comprehensive instructions, see Light Peer.

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#local-private-network","title":"Local Private Network","text":"

    Please refer to BSC-Deploy Tools to setup a local private network.

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#node-maintenance","title":"Node Maintenance","text":"

    Please read this guide

    "},{"location":"bnb-smart-chain/developers/node_operators/full_node/#upgrade-geth","title":"Upgrade Geth","text":"

    Please read this guide

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/","title":"Best Practices - BNB Smart Chain Node Configuration - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#bnb-smart-chain-bsc-node-configuration-best-practices","title":"BNB Smart Chain (BSC) Node Configuration: Best Practices","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#hardware-specifications","title":"Hardware Specifications","text":"

    To ensure optimal performance and reliability, it is crucial to select the appropriate node type based on your specific requirements for transaction processing and state querying on the BNB Smart Chain.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#fast-node-recommended-configuration","title":"Fast Node (Recommended Configuration)","text":"

    For users requiring access to the latest world state in a lightweight mode, the fast node is the ideal choice. It demands less from your system\u2019s CPU and disk space.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#archive-node","title":"Archive Node","text":"

    For comprehensive access to the entire historical world state of the BSC mainnet, consider deploying an Archive Node. Detailed instructions are available at BSC Erigon GitHub repository.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#full-node","title":"Full Node","text":"

    To obtain the latest world state and verify the validity of the state or to generate data proofs, a standard Full Node is suitable.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#peers-configuration","title":"Peers Configuration","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#mainnet","title":"Mainnet","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#testnet","title":"Testnet","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#clarification-of-the-snapshots","title":"Clarification of the snapshots","text":"

    As BSC will mainly support PBSS & PebbleDB, we will only cover snapshots of PBSS&PebbleDB and ignore snapshot of HashBased&LevelDB here. Please refer to this reference.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#troubleshooting-for-no-peers-in-testnet","title":"Troubleshooting for no peers in testnet","text":"

    Reference over here

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#monitoring-metrics-and-alerts","title":"Monitoring Metrics and Alerts","text":"

    To maintain node health and performance, monitor the following key metrics:

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#performance-optimization","title":"Performance Optimization","text":"

    BSC nodes offer configurable cache settings to enhance performance. It is advisable to allocate approximately one-third of the physical memory to the cache. For example, with 64GB of physical memory, the cache setting can be configured as:

    --cache 20000\n
    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#keep-track-of-syncing-speed","title":"Keep Track of Syncing Speed","text":"
    t=2021-05-13T17:17:17+0800 lvl=info msg=\"Imported new chain segment\"             blocks=11  txs=3701  mgas=482.461  elapsed=8.075s    mgasps=59.744  number=7,355,800 hash=0x84e085b1cd5b1ad4f9a954e2f660704c8375a80f04326395536eedf83363942f age=12h38m32s dirty=\"583.73 MiB\"\nt=2021-05-13T17:17:20+0800 lvl=info msg=\"Deep froze chain segment\"               blocks=117 elapsed=263.497ms number=7,265,806 hash=0x7602f6b960b4092d39ff49781c64404a047e2c78bc166f071ee8714020c39b2e\nt=2021-05-13T17:17:25+0800 lvl=info msg=\"Imported new chain segment\"             blocks=17  txs=5025  mgas=740.885  elapsed=8.125s    mgasps=91.177  number=7,355,817 hash=0xde7a2a76ff7b38414acf3b360bb427d2d0b7dd1f8fe2afe2ffd59d64b237a81b age=12h37m49s dirty=\"594.65 MiB\"\nt=2021-05-13T17:17:33+0800 lvl=info msg=\"Imported new chain segment\"             blocks=18  txs=5108  mgas=748.016  elapsed=8.354s    mgasps=89.535  number=7,355,835 hash=0x757c476f9fe30fc6ef001fb4a03fa991843cf3ed271f21cfc01a9bba5e5eff98 age=12h37m3s  dirty=\"604.39 MiB\"\nt=2021-05-13T17:17:42+0800 lvl=info msg=\"Imported new chain segment\"             blocks=18  txs=5612  mgas=799.778  elapsed=8.260s    mgasps=96.815  number=7,355,853 hash=0x73e87742ef4405ffefec987fc4b8b19e69c54b8f914c27ea69a502fae4d735e0 age=12h36m18s dirty=\"613.03 MiB\"\n

    Your syncing speed is mgasps. The value should be around 100. If you are syncing slowly, please check the speed of your disk.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#use-chaindata-snapshot","title":"Use Chaindata Snapshot","text":"

    Please download the chain data snapshot and extract to your home folder to speed up

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#store-your-bnb-with-a-hardware-wallet","title":"Store Your BNB with a Hardware Wallet","text":"

    The most valuable assets of a validator are two keys: one for signing transactions and another for signing blocks

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#securing-your-full-node-rpc-from-hackers","title":"Securing Your Full Node RPC from Hackers","text":"

    Please do not expose your RPC endpoints to public network.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#account-private-keys","title":"Account Private keys","text":"

    To protect your BNB, do not share your 24 words with anyone. The only person who should ever need to know them is you. In short, HSMs are affordable, performant and portable pieces of hardware that help to securely generate, store and manage your private keys. Malware attacks and remote extraction of private keys are much more difficult when an HSM is configured properly.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#software-vulnerabilities","title":"Software Vulnerabilities","text":"

    To protect your BNB, you should only download software directly from official sources, and make sure that you\u2019re always using the latest, most secure version

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#running-server-as-a-daemon","title":"Running Server as a Daemon","text":"

    It is important to keep geth running at all times. There are several ways to achieve this, and the simplest solution we recommend is to register geth as a systemd service so that it will automatically get started upon system reboots and other events.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#set-up-a-backup-node","title":"Set up a Backup Node","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#steps-to-run-a-backup-node","title":"Steps to Run a Backup Node","text":"
    1. Install the latest version of geth
    2. Sync to the latest height using fast sync mode. You can either download the latest snapshot or start fast sync once your node is fully synced
    3. Shut down your node gracefully kill -HUP $(pgrep geth)
    4. Restart your node.
    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#why-node-will-be-offline-for-a-while-after-restart-or-what-will-happen-if-the-client-is-force-killed","title":"Why Node will be Offline for a While After Restart? or What will Happen If the Client is Force Killed?","text":"

    After running (synchronized) for a long period of time and being abruptly terminated, only archived nodes are expected to quickly re-synchronize upon restart.

    Steps to reproduce:

    Reasons

    If Geth crashes (or is not shut down gracefully), the recent state held in memory is lost and needs to be regenerated. It takes Geth a long time to restore the states.

    The root reason is that geth does flush the state trie periodically. The period is defined as trieTimeout in config.toml.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#how-to-upgrade-a-backup-node-to-become-a-validator-node","title":"How to Upgrade a Backup Node to Become a Validator Node?","text":"

    You can stop mining new blocks by sending commands in geth console

    Connect to your validator node with geth attach ipc:path/to/geth.ipc

    miner.stop()\n

    Then, let backup node resume validating ,

    miner.start()\n
    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#securing-the-validators","title":"Securing the Validators","text":"

    Each validator candidate is encouraged to run its operations independently, as diverse setups increase the resilience of the network. Due to the high amount invested by validators it is highly essential to protect them against different DoS and DDoS attacks. In this section, we disscuss the security mechanism adopted by BSC for its validators.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#sentry-nodes-ddos-protection","title":"Sentry Nodes (DDOS Protection)","text":"

    Validators are responsible for ensuring that the network can sustain denial of service attacks. One recommended way to mitigate these risks is for validators to carefully structure their network topology in a so-called sentry node architecture. Sentry nodes can be quickly spun up or change their IP addresses. Because the links to the sentry nodes are in private IP space, an internet based attacked cannot disturb them directly. This will ensure validator block proposals and votes always make it to the rest of the network.

    To setup your sentry node architecture you can follow the instructions below:

    1. Build a private network and setup trusted private connections between the validator node and its sentry

    Please do not expose your validator fullnode RPC endpoints to the public network.

    Install your fullnode

    1. Set sentry as peers for the validator node

    In the console of the sentry node, run admin.nodeInfo.enode You should get something similar to this.

    enode://f2da64f49c30a0038bba3391f40805d531510c473ec2bcc7c201631ba003c6f16fa09e03308e48f87d21c0fed1e4e0bc53428047f6dcf34da344d3f5bb69373b@[::]:30306?discport=0\n

    !!! Note: [::] will be parsed as localhost (127.0.0.1). If your nodes are on a local network check each individual host machine and find your IP with ifconfig If your peers are not on the local network, you need to know your external IP address (use a service) to construct the enode URL. Copy this value and in the console of the first node run,

    Update config.toml file of validator node

    # make node invisible\nNoDiscovery = true\n# connect only to sentry\nStaticNodes = [\"enode://f2da64f49c30a0038bba3391f40805d531510c473ec2bcc7c201631ba003c6f16fa09e03308e48f87d21c0fed1e4e0bc53428047f6dcf34da344d3f5bb69373b@[10.1.1.1]:30306\"]\n
    This will return true if successful, but that doesn\u2019t mean the node was added successfully.

    To confirm run admin.peers and you should see the details of the node you just added.

    That way your validator node will try to peer with your provided sentry nodes only.

    1. Confirm the connection

    To confirm run admin.peers and you should see the details of the node you just added.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_best_practices/#firewall-configuration","title":"Firewall Configuration","text":"

    geth uses several TCP ports for different purposes.

    geth use a listener (TCP) port and a discovery (UDP) port, both on 30303 by default.

    If you need to run JSON-RPC, you\u2019ll also need TCP port 8545. Note that JSON-RPC port should not be opened to the outside world, because from there you can do admin operations.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/","title":"Node Maintenance - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#node-maintenance","title":"Node Maintenance","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#binary","title":"Binary","text":"

    All the clients are suggested to upgrade to the latest release. The latest version is supposed to be more stable and has better performance.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#storage","title":"Storage","text":""},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#prune-state","title":"Prune State","text":"

    According to the test, the performance of a full node will degrade when the storage size reaches a high volume(previously it was 1.5TB, which is an experimental value, the latest number needs to be updated). We suggest that the fullnode always keep light storage by pruning the storage.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#how-to-prune","title":"How to Prune","text":"
    1. Stop the BSC node.
    2. Run nohup geth snapshot prune-state --datadir {the data dir of your bsc node} &. It will take 3-5 hours to finish.
    3. Start the node once it is done.

    The maintainers should always have a few backup nodes in case one of the nodes is getting pruned. The hardware is also important, make sure the SSD meets: 3 TB of free disk space, solid-state drive(SSD), gp3, 8k IOPS, 500 MB/S throughput, read latency <1ms (if node is started with snap sync, it will need NVMe SSD).

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#prune-ancient-data-in-real-time","title":"Prune Ancient Data in Real Time","text":"

    Ancient data is block data that is already considered immutable. This is determined by a threshold which is currently set at 90000. This means that blocks older than 90000 are considered ancient data. We recommend the --prunceancient flag to users who don\u2019t care about the ancient data. This is also advised for users who want to save disk space since this will only keep data for the latest 90000 blocks. Note that once this flag is turned on, the ancient data will not be recovered again and you cannot go back running your node without this flag in the start-up command.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#how-to-use-the-flag","title":"How to use the flag","text":"
    ./geth --tries-verify-mode none --config /server/config.toml --datadir /server/node --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0 --pruneancient=true --syncmode=full\n
    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#prune-block-tools","title":"Prune Block Tools","text":"

    A new offline feature introduced in v1.1.8 to prune undesired ancient block data. It will discard block, receipt, and header in the ancient database to save space.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#how-to-prune_1","title":"How to prune","text":"
    1. Stop the BSC Node.
    2. Run

      ./geth snapshot prune-block --datadir /server/node --datadir.ancient ./chaindata/ancient --block-amount-reserved 1024\n

      block-amount-reserved is the number of ancient data blocks that you want to keep after pruning.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#light-storage","title":"Light Storage","text":"

    When the node crashes or been force killed, the node will sync from a block that was a few minutes or a few hours ago. This is because the state in memory is not persisted into the database in real time, and the node needs to replay blocks from the last checkpoint once it start. The replaying time depends on the configuration TrieTimeout in the config.toml. We suggest you raise it if you can tolerate with long replaying time, so the node can keep light storage.

    "},{"location":"bnb-smart-chain/developers/node_operators/node_maintenance/#upgrade-geth","title":"Upgrade Geth","text":"

    Please read this guide

    "},{"location":"bnb-smart-chain/developers/node_operators/reth_node/","title":"Reth Node - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/reth_node/#reth-node-for-bsc","title":"Reth Node for BSC","text":"

    BSC Reth is a cutting-edge Rust client developed in collaboration with Paradigm, designed to provide seamless support for BNB Smart Chain (BSC). It aims to enhance client diversity on the BNB Chain by offering a secure and efficient execution client.

    "},{"location":"bnb-smart-chain/developers/node_operators/reth_node/#hardware-specifications","title":"Hardware Specifications","text":"

    To run BSC Reth effectively, ensure your system meets the following hardware requirements:

    "},{"location":"bnb-smart-chain/developers/node_operators/reth_node/#running-bsc-reth","title":"Running BSC Reth","text":"
    1. Download source code and build binary.

      git clone https://github.com/bnb-chain/reth.git\ncd reth\nmake build-bsc\n
    2. Start the reth node, it will run in archive mode by default. You can add the --full flag to start a full node.

      # for mainnet\nexport network=bsc\n\n# for testnet\n# export network=bsc-testnet\n\n./target/release/bsc-reth node \\\n    --datadir=./datadir \\\n    --chain=${network} \\\n    --http \\\n    --http.api=\"eth, net, txpool, web3, rpc\" \\\n    --log.file.directory ./datadir/logs\n
    3. Optionally, you can run the reth node with docker.

      # for mainnet\nexport network=bsc\n\n# for testnet\n# export network=bsc-testnet\n\n# check this for version of the docker image, https://github.com/bnb-chain/reth/pkgs/container/bsc-reth\nexport version=latest\n\n# the directory where reth data will be stored\nexport data_dir=/xxx/xxx\n\ndocker run -d -p 8545:8545 -p 30303:30303 -p 30303:30303/udp -v ${data_dir}:/data \\\n    --name bsc-reth ghcr.io/bnb-chain/bsc-reth:${version} node \\\n    --datadir=/data \\\n    --chain=${network} \\\n    --http \\\n    --http.api=\"eth, net, txpool, web3, rpc\" \\\n    --log.file.directory /data/logs\n
    "},{"location":"bnb-smart-chain/developers/node_operators/reth_node/#snapshot","title":"Snapshot","text":"

    To synchronize a BSC reth node from scratch to the current block height can be a time-consuming process. As We benchmark Reth(v1.0.0) on AWS lm4gn.8xlarge(32 core 128G) with 2 x 7500 NVMe SSD for BSC mainnet. It may take approximately 30 days to sync the latest block on BSC mainnet for an archive node and 24 days for a full node.

    Given the extended duration required for stage synchronization of the BSC network, the BNB Chain team is developing a segmented snapshot download solution, scheduled for release in the near future. Currently, developers seeking to expedite the process can obtain archive node snapshots from community-maintained repositories. These snapshots offer a faster alternative to syncing from genesis, allowing for quicker node setup and network participation.

    "},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/","title":"Upgrade Geth - BSC Develop","text":""},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/#how-to-upgrade-geth","title":"How to Upgrade Geth","text":"

    Updating geth is as easy as it gets. You just need to download and install the newer version of geth, shutdown your node and restart with the new software. Geth will automatically use the data of your old node and sync the latest blocks that were mined since you shut down the old software.

    "},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/#step-1-compile-the-new-version-or-download-new-pre-build-binaries-from-release","title":"Step 1: Compile the New Version or download new pre-build binaries from release","text":"
    git clone https://github.com/bnb-chain/bsc\n# Enter the folder bsc was cloned into\ncd bsc\n# Compile and install bsc\nmake geth\n
    # Download pre-build binaries\n\n# Linux\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_linux |cut -d\\\" -f4)\nmv geth_linux geth\nchmod -v u+x geth\n\n# MacOS\nwget   $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_mac |cut -d\\\" -f4)\nmv geth_mac geth\nchmod -v u+x geth\nmake geth\n
    "},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/#step-2-stop-geth","title":"Step 2: Stop Geth","text":"
    $ pid=`ps -ef | grep geth | grep -v grep | awk '{print $2}'`\n$ kill  $pid\n
    "},{"location":"bnb-smart-chain/developers/node_operators/upgrade_geth/#step-3-restart","title":"Step 3: Restart","text":"

    Note

    Make sure to use the same start-up command you used before the upgrade. So in this case we use the same command as in our tutorial

    ./geth --config ./config.toml --datadir ./node --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0\n
    "},{"location":"bnb-smart-chain/developers/paymaster/overview/","title":"Overview - BSC Paymaster","text":""},{"location":"bnb-smart-chain/developers/paymaster/overview/#eoa-based-paymaster","title":"EOA Based Paymaster","text":"

    This document introduces a paymaster solution specifically designed for Externally Owned Account (EOA) wallets, differing from the paymaster defined in EIP-4337. With minimal modifications, wallets can integrate this solution to support gas fee sponsorship, significantly enhancing user experience.

    "},{"location":"bnb-smart-chain/developers/paymaster/overview/#what-is-eoa-based-paymaster","title":"What is EOA based Paymaster","text":"

    The paymaster in EIP-4337 (Account Abstraction via Entry Point Contract Specification) is a crucial component designed to enhance the flexibility and user experience of Ethereum transactions. It allows a third party to pay for a user\u2019s transaction fees, removing the need for users to hold ETH to pay for gas.

    While EIP-4337 introduced the revolutionary concept of paymasters for smart contract wallets, a significant portion of the Ethereum ecosystem still relies on EOAs. Recognizing this, this present a groundbreaking paymaster solution specifically designed for EOA wallets. This innovation brings the benefits of transaction sponsorship and enhanced user experience to the broader BNB Chain user base, without requiring a shift to smart contract wallets. The EOA paymaster solution aims to democratize access to sponsored transactions, making blockchain interactions more user-friendly and cost-effective for millions of existing EOA wallet users.

    "},{"location":"bnb-smart-chain/developers/paymaster/overview/#how-does-it-work","title":"How does it Work","text":"

    Under BEP322\u2019s Proposer-Builder Separation (PBS) architecture, a significant shift occurs in transaction processing:

    1. Validator Role: Validators no longer verify individual transaction gas prices within a block.
    2. Transaction Bundling: Private transactions are grouped into bundles and submitted to builders.
    3. Prioritization: Builders prioritize based on the aggregate gas price of each bundle.
    4. Intra-Bundle Flexibility: Within a single bundle, gas prices can vary, allowing for zero-fee and higher-fee transactions to coexist.

    This flexibility enables innovative features such as sponsored gas fees and gasless transactions.

    "},{"location":"bnb-smart-chain/developers/paymaster/overview/#definitions","title":"Definitions","text":"

    Bundle: An ordered array of transactions that execute atomically, ensuring all transactions in the bundle are processed together or not at all.

    Builder: A new stakeholder in the MEV supply chain responsible for constructing blocks. Builders package transaction bundles, individual transactions from the public txpool, and private transaction order flow into proposed blocks.

    Proposer: A validator who selects the most profitable block from multiple builders\u2019 proposals for inclusion in the blockchain.

    Paymaster: An infrastructure component that enables transaction sponsorship, allowing self or third parties to cover gas fees.

    Sponsor Policy: A set of rules defined by the gas sponsor to determine which transactions qualify for sponsorship. This may include criteria such as whitelisted transaction senders or specific transaction types.

    "},{"location":"bnb-smart-chain/developers/paymaster/overview/#overall-workflow","title":"Overall Workflow","text":"

    The gas sponsorship process involves several key components and steps:

    1. User Initiation:

    2. Paymaster Submission:

    3. Sponsor Policy Verification:

    4. Sponsorship Processing:

    5. Bundle Creation and Submission:

    6. Builder Selection and Block Proposal:

    7. Blockchain Inclusion:

    8. Post-Transaction Processing:

    This solution leverages the BEP322 Proposer-Builder Separation architecture to enable seamless gas sponsorship without requiring significant changes to existing wallet infrastructures. It provides a flexible system that can accommodate various sponsorship models while maintaining the security and integrity of the blockchain network.

    "},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/","title":"Paymaster-API - BSC Paymaster","text":""},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#paymaster-api-spec","title":"Paymaster API Spec","text":"

    To facilitate widespread adoption and ensure interoperability across diverse wallet implementations, it is crucial to establish a standardized set of interface specifications for paymasters. This standardization will enable wallet developers to integrate gas sponsorship features efficiently and consistently, regardless of the specific paymaster service they choose to utilize.

    "},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#api-spec","title":"API Spec","text":"

    Paymaster needs to implement a JSON-RPC API called\u00a0pm_isSponsorable, so that it can return sponsor and policy information to wallets. Paymaster also needs to implement\u00a0eth_sendRawTransaction\u00a0JSON-RPC API. The detailed API Specs are defined as below:

    "},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#pm_issponsorable","title":"pm_isSponsorable","text":"

    Request Parameters

    Example:

    {\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"method\": \"pm_isSponsorable\",\n  \"params\": [\n    {\n      \"to\": \"0x...\", // an address\n      \"from\": \"0x...\", // an address\"value\": \"0xa1\",\n      \"data\": \"0x\",\n      \"value\": \"0x1b4\",\n      \"gas\" : \"0x101b4\"\n    }\n  ]\n}\n

    Response Fields

    Example:

    {\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"result\": {\n    \"Sponsorable\": true,\n    \"SponsorPolicy\": \"a sample policy name\"\n  }\n}\n
    "},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#_1","title":"Paymaster-API - BSC Paymaster","text":""},{"location":"bnb-smart-chain/developers/paymaster/paymaster-api/#eth_sendrawtransaction","title":"eth_sendrawtransaction","text":"

    The\u00a0eth_sendrawtransaction\u00a0API implemented by the Paymaster should follow this\u00a0Ethereum API Spec. The client can create a new message call transaction or a contract creation for signed transactions via\u00a0eth_sendrawtransaction\u00a0API.

    Request Parameters

    The\u00a0params\u00a0should contain the signed transaction data.

    Example:

    {\n   \"jsonrpc\": \"2.0\",\n   \"id\": 1,\n   \"method\": \"eth_sendRawTransaction\",\n   \"params\": [\n \"0x02f86a6102850df8475800850df84758000a94cd9c02358c223a3e788c0b9d94b98d434c7aa0f18080c080a0bcb0e8ffa344e4b855c6e13ee9e4e5d22cff6ad8bd1145a93b93c5d332100c2ca03765236eba5fbb357e35014fd19ba4b3c6b87f3793bd14dddf7913fc8dcc88bf\"\n   ]\n}\n

    Response Fields

    DATA, 32 Bytes - the transaction hash.

    Example:

    {\n  \"id\":1,\n  \"jsonrpc\": \"2.0\",\n  \"result\": \"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331\"\n}\n
    "},{"location":"bnb-smart-chain/developers/paymaster/wallet-integration/","title":"Paymaster Wallet Integration - BSC Paymaster","text":""},{"location":"bnb-smart-chain/developers/paymaster/wallet-integration/#wallet-integration","title":"Wallet Integration","text":"

    This guide outlines the steps for wallet developers to integrate paymaster services, enabling gas fee sponsorship for their users. By following these standards, wallets can offer seamless, gasless transactions across multiple paymaster providers.

    "},{"location":"bnb-smart-chain/developers/paymaster/wallet-integration/#interaction-workflow","title":"Interaction Workflow","text":"

    Integration involves modifying the transaction creation and sending process to interact with paymaster services. For detailed information about the paymaster API interface, please refer to this document.

    The main steps are:

    1. Transaction Preparation:
    2. User Notification:
    3. Transaction Signing:
    4. Submission to Paymaster:
    5. Response Handling:
    6. Transaction Monitoring:
    "},{"location":"bnb-smart-chain/developers/paymaster/wallet-integration/#best-practice","title":"Best Practice","text":"
    1. Always check sponsorability before modifying gas price.
    2. Provide clear user feedback about sponsorship status.
    3. Implement proper error handling for cases where sponsorship fails.
    4. Consider fallback mechanisms for non-sponsored transactions.
    "},{"location":"bnb-smart-chain/governance/apis/","title":"Governance APIs - BSC Governance","text":""},{"location":"bnb-smart-chain/governance/apis/#bsc-governance-apis","title":"BSC Governance APIs","text":"

    This guide gives an overview of governance operations for BSC, such as creating proposals, casting votes, and executing them.

    "},{"location":"bnb-smart-chain/governance/apis/#governance-contracts","title":"Governance Contracts","text":"

    The BSC governance facilitates decentralized decision-making within the BSC ecosystem, utilizing two primary smart contracts: GovToken for governance token management and Governor for proposal management and voting.

    "},{"location":"bnb-smart-chain/governance/apis/#create-proposal","title":"Create Proposal","text":"

    To create a proposal, you need to call the propose function of Governor with the following parameters:

    function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory\n    description) public returns (uint256 proposalId)\n
    "},{"location":"bnb-smart-chain/governance/apis/#cast-vote","title":"Cast Vote","text":"

    To cast a vote, you need to call the castVote function of Governor with the following parameters:

    function castVote(uint256 proposalId, uint8 support, string memory reason) public returns (uint256)\n
    "},{"location":"bnb-smart-chain/governance/apis/#check-proposal-state","title":"Check Proposal State","text":"

    To get the state of a proposal, you need to call the state function of Governor with the following parameters:

    function state(uint256 proposalId) public view returns (ProposalState)\n
    "},{"location":"bnb-smart-chain/governance/apis/#queue-proposal","title":"Queue Proposal","text":"

    To schedules the proposal for execution, you need to call the queue function of Governor with the following parameters:

    function queue(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)\npublic returns (uint256 proposalId)\n
    "},{"location":"bnb-smart-chain/governance/apis/#execute-proposal","title":"Execute Proposal","text":"

    To apply the changes after the timelock delay, you need to call the execute function of Governor with the following parameters:

    function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)\npublic payable returns (uint256)\n
    "},{"location":"bnb-smart-chain/governance/apis/#delegate-vote","title":"Delegate Vote","text":"

    To delegate voting power to someoneles, you need to call the delegateVote function of GovToken with the following parameters:

    function delegateVote(address delegator, address delegatee) external\n
    "},{"location":"bnb-smart-chain/governance/apis/#contract-abi","title":"Contract ABI","text":"

    For the full interfaces of Governor, please refer to the ABI file.

    For the full interfaces of GovToken, please refer to the ABI file.

    "},{"location":"bnb-smart-chain/governance/overview/","title":"Overview - BSC Governance","text":""},{"location":"bnb-smart-chain/governance/overview/#bsc-governance-overview","title":"BSC Governance Overview","text":"

    BEP-297 introduces the native governance module for BSC, drawing inspiration from the OpenZeppelin Governor. Here are the key features of BSC Governance:

    "},{"location":"bnb-smart-chain/governance/overview/#workflow-overview","title":"Workflow Overview","text":""},{"location":"bnb-smart-chain/governance/overview/#submit-proposal","title":"Submit Proposal","text":""},{"location":"bnb-smart-chain/governance/overview/#cast-vote","title":"Cast Vote","text":""},{"location":"bnb-smart-chain/governance/overview/#execute-proposal","title":"Execute Proposal","text":""},{"location":"bnb-smart-chain/governance/overview/#delegation-of-voting-power","title":"Delegation of Voting Power","text":"

    Staking credit holders can delegate their voting power to participate in governance if they lack time or expertise. Delegating to a trusted party like a validator or a professional service allows them to benefit from expertise and avoid losing rewards by not voting.

    "},{"location":"bnb-smart-chain/governance/temp-check/","title":"Temperature Check - BSC Governance","text":""},{"location":"bnb-smart-chain/governance/temp-check/#bsc-governance-temperature-check","title":"BSC Governance Temperature Check","text":""},{"location":"bnb-smart-chain/governance/temp-check/#overview","title":"Overview","text":"

    BNB Chain governance involves a two-step process: temperature check and final decision voting. The temperature check, typically conducted through the Snapshot platform, allows any BNB holder to gauge community sentiment on a proposal. If the proposal receives enough support, it proceeds to the final decision voting phase. This phase often involves on-chain voting by validators or those with staked BNB, and the outcome determines whether the proposal is implemented or rejected.

    "},{"location":"bnb-smart-chain/governance/temp-check/#submit-a-proposal","title":"Submit a Proposal","text":"

    Info

    Anyone who staked more than 1BNB can create proposals.

    Step 1: Head to the space which you wish to create your proposal for.

    Connect with the wallet provider - make sure the connected wallet is where you delegate BNB

    Step 2: Click New proposal in space sidebar

    Fill in the following fields: - Title - Description - Discussion link

    Step 3: Select the desired voting system, specify the possible vote options, and define the duration of your proposal. Make sure you allow enough time for users to vote.

    Step 4: Click Publish - and you can see your proposal in the proposals list on the space page.

    "},{"location":"bnb-smart-chain/governance/temp-check/#voting","title":"Voting","text":""},{"location":"bnb-smart-chain/governance/temp-check/#vote-on-a-proposal","title":"Vote on a Proposal","text":"

    Info

    All BNBChain delegators can vote for proposals.

    Step 1: Log in to voting space URL: https://snapshot.org/#/bnbchain-dao.eth

    Step 2: Go to the snapshot link of the proposal. For example, in this case, a community member created a voting proposal for BEP-341.

    https://snapshot.org/#/bnbchain-dao.eth/proposal/0xd2ad975fbe1abd4bf71a5032239650741a64af0133feec83f43b98bc42fa7efe

    Step 3: Connect your wallet and vote

    After you connect your wallet, make sure to use the same address of your BNB Staking. And choose the voting option.

    "},{"location":"bnb-smart-chain/governance/temp-check/#delegate-voting-power","title":"Delegate Voting Power","text":"

    Step 1: Go to https://snapshot.org/#/delegate/bnbchain-dao.eth

    Step 2: Enter the address you want to delegate to.

    Step 3: Click Confirm to save your delegation.

    "},{"location":"bnb-smart-chain/governance/temp-check/#undelegate-voting-power","title":"Undelegate Voting Power","text":"

    Step 1: Go to https://snapshot.org/#/delegate/bnbchain-dao.eth

    Step 2: Find the current delegatees in Top delegates.

    Step 3: Click the \u2018x\u2019 button along a delegatee to undelegate, the wallet will ask user to sign and send transaction to bsc

    "},{"location":"bnb-smart-chain/governance/user-guide/","title":"User Guide - BSC Governance","text":""},{"location":"bnb-smart-chain/governance/user-guide/#manage-governance-with-tally-dapp","title":"Manage Governance with Tally dApp","text":"

    This document provides a guide on how to participate in governance on the BNB Smart Chain (BSC) using Tally. It covers the process of delegating voting power, creating proposals, voting on proposals, and executing proposals.

    BNB Chain DAOs are created on Tally both for the mainnet and testnet.

    "},{"location":"bnb-smart-chain/governance/user-guide/#parameters","title":"Parameters","text":"

    There are several parameters which will affect the governance process on the BSC.

    Parameter Description Mainnet Value Testnet Value votingDelay a fixed duration after which users can vote to a proposal 0 hour 0 hour votingPeriod the voting period before tally 7 days 1 day proposalThreshold a fixed amount of gov BNB needed for a proposal 200 govBNB 100 govBNB quorumNumberRator the percentage of the total voting power required to produce a final vote result 10% 10% startGovThreshold the total supply of gov token to enable the gov function 10M BNB 10M BNB minPeriodAfterTheQuorum the time to add for voting when a proposal reaches quorum 1 day 1 hour timerlockDelay the timer locker duration to execute a proposal 1 day 6 hours"},{"location":"bnb-smart-chain/governance/user-guide/#governance-process-guide","title":"Governance Process Guide","text":"

    You need to connect to your Web3 wallet (e.g., TrustWallet, BEW, Metamask) for the following operations.

    "},{"location":"bnb-smart-chain/governance/user-guide/#delegate-voting-power","title":"Delegate Voting Power","text":"

    After you have delegated your BNB to a BSC validator, you can start participating in the BSC governance. To participate in BSC governance, you first need to delegate your voting power to a validator or yourself if you wish to vote directly.

    You can click the My voting power button in the top right corner of the screen to delegate your voting power.

    You can delegate your voting power to yourself if you want to vote/create proposals directly, or to others if you want him/her to vote/create proposals on your behalf.

    If you delegate the voting power to yourself, you will see the current number of your voting power to participate in the governance.

    "},{"location":"bnb-smart-chain/governance/user-guide/#create-proposals","title":"Create Proposals","text":"

    If you have sufficient voting power (i.e., greater than the proposalThreshold), you can create proposals on the BSC network. Be noted that a user can only has one proposal in active/pending state at a time to prevent spamming.

    To create a proposal, click on the \u201cCreate new proposal\u201d button on the top right corner of the screen.

    After you have created a proposal, you can add a title, description, and a list of actions for the proposal.

    A text proposal only requires a title and a description, and it will not be executed by the network for there is no action.

    To add an action, click on the \u201cAdd action\u201d button, and fill in the details of the action.

    After you input all the details, click on the \u201cPublish\u201d will publish your proposal.

    You can also cancel a proposal by clicking on the \u201cCancel proposal\u201d button.

    "},{"location":"bnb-smart-chain/governance/user-guide/#vote-on-proposals","title":"Vote on Proposals","text":"

    Once a proposal is live (i.e., after the votingDelay and before the votingPeriod), you can cast your vote to support or oppose the proposal. To vote on a proposal, click on the \u201cVote on chain\u201d button.

    You can cast For, or Against, or Abstain votes to the proposal.

    "},{"location":"bnb-smart-chain/governance/user-guide/#execute-proposals","title":"Execute Proposals","text":"

    If a proposal reaches the quorum (i.e., reaches the quorumNumberRator of the total voting power) and it passes (i.e., more than 50% of the voted voting power supports the proposal), it can be executed by the network.

    To execute a proposal, firstly the proposal needs to be queued by clicking the Queue button.

    After the proposal is queued and exceeds the timelock duration (i.e, the timerlockDelay duration), it can be executed by anyone by clicking the Execute button.

    "},{"location":"bnb-smart-chain/governance/user-guide/#more-references","title":"More References","text":""},{"location":"bnb-smart-chain/slashing/monitor/","title":"Monitor - BSC Slashing","text":""},{"location":"bnb-smart-chain/slashing/monitor/#bsc-slash-monitor","title":"BSC Slash Monitor","text":""},{"location":"bnb-smart-chain/slashing/monitor/#monitor-slash","title":"Monitor Slash","text":"

    Generally, without maliciously altering BSC node code or mistakenly running the validator, validators would not typically incur double sign slashes or malicious vote slashes.

    Validators should consistently monitor for potential slashes due to node unavailability, as it can lead to slash events.

    As best practice, it is advisable to keep monitoring the event log of the slash contract on the BSC scanner at https://bscscan.com/address/0x0000000000000000000000000000000000001001#events.

    You can check your validator\u2019s slash indicator in the above contract. Pay attention to values above 30. If it goes over 50, the validator will be slashed. If it goes over 150, the validator will be jailed.

    "},{"location":"bnb-smart-chain/slashing/monitor/#unjail-validator","title":"Unjail Validator","text":"

    Once a Validator is slashed into a jailed state, the Validator must wait for a specific period before being able to unjail. Once the waiting period elapses, the Validator can access the BNB Staking dApp and proceed to click on the unjail button to initiate the unjail transaction.

    BNB Staking dApp:

    "},{"location":"bnb-smart-chain/slashing/overview/","title":"Overview - BSC Slashing","text":""},{"location":"bnb-smart-chain/slashing/overview/#bsc-slashing-overview","title":"BSC Slashing Overview","text":"

    Slashing is a component of on-chain governance that penalizes malicious or negative actions. Anyone can submit a slash transaction on BSC, which involves providing evidence and paying fees. Successful submissions yield significant rewards. Currently, there are three types of slashable cases.

    "},{"location":"bnb-smart-chain/slashing/overview/#double-sign","title":"Double Sign","text":"

    It is quite a serious error and very likely a deliberate offense when a validator signs more than one block with the same height and parent block. The reference protocol implementation should already have logic to prevent this, so only the malicious code can trigger this. When Double Sign happens, the validator should be removed from the Validator Set right away.

    Anyone can submit a slash transaction with the evidence of Double Sign to the BSC Slash Contract, which should contain the 2 block headers with the same height and parent block, sealed by the offending validator. Upon receiving the evidence, the contract will verify its validity.

    The validator will be removed from validator set, a predefined amount of BNB would be slashed from the self-delegated BNB of the validator. Both validator and its delegators will not receive the staking rewards. Part of the slashed BNB will be allocated to the submitter\u2019s address, which is a reward and larger than the cost of submitting slash request transaction. The rest of the slashed BNB will be allocated to the other validators\u2019 credit addresses, and distributed to all delegators in the same way as blocking reward.

    "},{"location":"bnb-smart-chain/slashing/overview/#malicious-fast-finality-vote","title":"Malicious Fast Finality Vote","text":"

    It is quite a serious error and very likely a deliberate offense when a validator signs two fast finality votes with the same target height or the span of one vote including the span of another vote. The reference protocol implementation should already have logic to prevent this, so only the malicious code can trigger this. When Malicious Vote happens, the validator should be removed from the Validator Set right away.

    Anyone can submit slash transaction with the evidence of Malicious Vote to the BSC Slash Contract. Evidence of malicious voting needs to be provided, which includes two conflicting votes and the voting key used for the signature. Upon receiving the evidence, the contract will verify its validity.

    The validator will be removed from the current set of validators, and the submitter will receive the reward from the system contract. A predefined amount of BNB would be slashed from the self-delegated BNB of the validator. Both validator and its delegators will not receive the staking rewards. The slashed BNB will be allocated to the other validators\u2019 credit addresses, and distributed to all delegators in the same way as blocking reward.

    "},{"location":"bnb-smart-chain/slashing/overview/#unavailability","title":"Unavailability","text":"

    The liveness of BSC relies on everyone in the Proof of Staked Authority validator set can produce blocks timely when it is their turn. Validators can miss their turn due to any reason, especially problems in their hardware, software, configuration or network. This instability of the operation will hurt the performance and introduce more indeterministic into the system.

    There is an internal smart contract that records the missed blocking metrics of each validator. If the metrics exceed the set threshold, the blocking reward for the validator will not be given to them but shared with other validators performing better. This process aims to gradually remove poorly-operating validators from the set, reducing rewards for their delegators.

    If the metrics stay above a higher threshold, the validator will be removed from rotation, and a set amount of BNB will be deducted from their self-delegated BNB. This action results in both validators and delegators not receiving their staking rewards.

    "},{"location":"bnb-smart-chain/slashing/slash-rules/","title":"BSC Slash Rules - BSC Slashing","text":""},{"location":"bnb-smart-chain/slashing/slash-rules/#bsc-slash-rules","title":"BSC Slash Rules","text":"

    Three types of malicious behaviors can lead to slashing on the BSC network.

    "},{"location":"bnb-smart-chain/slashing/slash-rules/#double-sign","title":"Double Sign","text":"

    Anyone can submit a slash request with evidence of Double Sign. The evidence must adhere to the following rules:

    If the evidence is valid:

    1. 200BNB would be slashed from the self-delegated BNB of the validator
    2. The remaining slashed BNB will be allocated to the credit addresses of validators participating in the next distribution
    3. Set the validator jailed with a duration of 30 days, and remove it from the active validator set
    "},{"location":"bnb-smart-chain/slashing/slash-rules/#malicious-vote","title":"Malicious Vote","text":"

    Anyone can submit a slash request on BSC with the evidence of Malicious Vote. The evidence must adhere to the following rules:

    If the evidence is valid:

    1. 200BNB would be slashed from the self-delegated BNB of the validator
    2. 5BNB would allocate to the submitter from the system reward contract as a reward if the validator is active when the evidence submitted
    3. The remaining slashed BNB will be allocated to the credit addresses of validators participating in the next distribution
    4. Set the validator jailed with a duration of 30 days, and remove it from the active validator set
    "},{"location":"bnb-smart-chain/slashing/slash-rules/#unavailability","title":"Unavailability","text":"

    There is an internal smart contract that records the missed blocking metrics of each validator.

    If a validator misses over 50 blocks in 24 hours, they will not receive the block reward; instead, it will be shared among other validators.

    If a validator misses more than 150 blocks in 24 hours:

    1. 10BNB would be slashed from the self-delegated BNB of the validator
    2. The slashed BNB will be allocated to the credit addresses of validators participating in the next distribution
    3. Set the validator jailed with a duration of 2 days, and remove it from the active validator set
    "},{"location":"bnb-smart-chain/staking/developer-guide/","title":"Build BSC Staking dApps Guide - BSC Staking","text":""},{"location":"bnb-smart-chain/staking/developer-guide/#build-bsc-staking-dapps-guide","title":"Build BSC Staking dApps Guide","text":"

    This guide covers essential staking operations like creating validators, editing their information, and delegating. Developers can use these interfaces to build stake-related dApps.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#stakehub-contract","title":"StakeHub Contract","text":"

    The BSC staking mainly uses the smart contracts StakeHub for validator and delegation management.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#creating-validator","title":"Creating Validator","text":"

    To create a validator, use the createValidator function with the following parameters:

      function createValidator(\n    address consensusAddress,\n    bytes calldata voteAddress,\n    bytes calldata blsProof,\n    Commission calldata commission,\n    Description calldata description\n) external payable\n

    Note: Creating a validator requires locking 1 BNB, and the transaction must be sent with a sufficient BNB amount to cover this lock amount plus any self-delegation, in total 2001BNB.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#edit-validator","title":"Edit Validator","text":""},{"location":"bnb-smart-chain/staking/developer-guide/#edit-consensus-address","title":"Edit Consensus Address","text":"

    To change the consensus address of a validator, use the editConsensusAddress function with the following parameters:

    function editConsensusAddress(address newConsensusAddress) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#edit-commission-rate","title":"Edit Commission Rate","text":"

    To update the commission rate of a validator, use the editCommissionRate function with the following parameters:

    function editCommissionRate(uint64 newCommissionRate) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#edit-description","title":"Edit Description","text":"

    To update the description of a validator, use the editDescription function with the following parameters:

    function editDescription(Description memory newDescription) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#edit-vote-address","title":"Edit Vote Address","text":"

    To change the vote address of a validator, use the editVoteAddress function with the following parameters:

    function editVoteAddress(bytes calldata newVoteAddress, bytes calldata blsProof) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#delegation-operations","title":"Delegation Operations","text":""},{"location":"bnb-smart-chain/staking/developer-guide/#delegate","title":"Delegate","text":"

    To delegate BNB to a validator, call the delegate function with the following parameters:

    function delegate(address operatorAddress, bool delegateVotePower) external payable\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#undelegate","title":"Undelegate","text":"

    To undelegate BNB from a validator, use the undelegate function with the following parameters:

    function undelegate(address operatorAddress, uint256 shares) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#redelegate","title":"Redelegate","text":"

    To redelegate BNB from one validator to another, use the redelegate function with the following parameters:

    function redelegate(address srcValidator, address dstValidator, uint256 shares, bool delegateVotePower) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#claim","title":"Claim","text":"

    To claim undelegated BNB after the unbonding period, use the claim function for a single request or claimBatch for multiple requests:

    function claim(address operatorAddress, uint256 requestNumber) external\n
    function claimBatch(address[] calldata operatorAddresses, uint256[] calldata requestNumbers) external\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#precision-loss","title":"Precision Loss","text":"

    During the conversion process between credit tokens and BNB, it is inevitably encounter the usage of integer division, which may results in a precision loss. It can lead to tangible issues. For example, a user who delegates 1 BNB and then decides to undelegate immediately. Due to the aforementioned precision loss, they will only be able to claim back 0.99..99 BNB, which is essentially 1 minus a tiny fraction (1e-18) of BNB.

    In staking pools like Lido and Rocket Pool, users might encounter similar issues. However, these issues can be effectively addressed through thoughtful product design. For instance, when displaying information to users, rounding up to only preserve eight decimal places could be one solution. Or instead of undelegating, users can exchange their credit tokens for BNB, with the exact conversion results prominently displayed.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#faqs","title":"FAQs","text":""},{"location":"bnb-smart-chain/staking/developer-guide/#what-is-validators-credit-contract","title":"What is validator\u2019s credit contract?","text":"

    For each validator, there is a credit contract which will be automatically deployed when it is created. Meanwhile, the contract cannot be upgraded or changed by any validator operator.

    The credit contract is a BEP20 contract, and the ABI is the same as Stake Credit contract.

    It provides functions for querying delegations, including:

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-the-sharesbnb-for-a-delegator","title":"How to get the shares/BNB for a delegator?","text":"

    For any specific validator, please call the balanceOf function of the validator\u2019s creat contract to get the delegator\u2019s shares. To get the BNB amount instead of shares, the function getPooledBNB can be used.

    To get the shares of all validators, please call the balanceOf function for each validator and sum up the results. Please refer to the following to see how to get the information of all validators, and use a muticall contract to improve the efficiency.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-calculate-the-bnb-amount-for-a-specific-amount-of-shares","title":"How to calculate the BNB amount for a specific amount of shares?","text":"

    The credit contract provides the getPooledBNBByShares function to calculate the BNB amount for some specific amount of shares.

    To do the vice visa, please use the getSharesByPooledBNB function to calculate the shares for some specific BNB amount.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-calculate-the-aprapy-of-a-validator","title":"How to calculate the APR/APY of a validator?","text":"

    Please be noted that each validator will have its own APR/APY, and the staking system will auto compound the rewards.

    The reward is distributed to each validator\u2019s BNB pool at 00:00:00 UTC time every day. To calculate the APR/APY of a validator, the total pooled BNB amount and the propagandising reward amount for the same day are needed.

    The StakeHub contract provides the getValidatorTotalPooledBNBRecord(address,uint256)(uint256) and getValidatorRewardRecord(address,uint256)(uint256) for the purpose.

    The following code shows how to calculate the APY at a given day:

    // example code, do not use it in production\n\n// stakehub is the instance of StakeHub contract\nstakeHub, _ := contracts.NewStakeHub(ethcommon.HexToAddress(\"0x0000000000000000000000000000000000002002\"), client.GetEthClient())\n\n// get how many blocks are in a day\ninterval, _ := stakeHub.BREATHEBLOCKINTERVAL(nil)\n\n// get the block time of a given block\nheader, _ := p.client.GetBlockHeader(blockHeight)\n\n// calculate the index paramter to call the following functions\nindex := int64(header.Time) / interval.Int64()\n\n// get the total pooled BNB amount and the crrospanding reward amount for the given validator and index\ntotalPooledBNB, _ := stakeHub.GetValidatorTotalPooledBNBRecord(nil, validatorOperatorAddress, index)\nreward, _ := stakeHub.GetValidatorRewardRecord(nil, validatorOperatorAddress, index)\n\n// calculate the APY\nrate, _ := big.NewFloat(0).Quo(big.NewFloat(0).SetInt(reward), big.NewFloat(0).SetInt(totalPooledBNB)).Float64()\napy := math.Pow(1+rate, 365) - 1.0\n
    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-the-unbonding-delegations-of-a-delegator-and-the-unbonded-requests-which-can-be-claimed","title":"How to get the unbonding delegations of a delegator, and the unbonded requests which can be claimed?","text":"

    The credit contract provides the pendingUnbondRequest function to get the unbonding delegation count for a delegator. To review the details of an unbond request, please call the unbondRequest function with a index parameter to define which unbond request will be returned.

    To get the claimable unbonded requests, please call the claimableUnbondRequest function to get the count of claimable ones.

    To get the locked BNBs for unbonding requests, please use the lockedBNBs function. It has the parameter number to define the sum of first number unbonding requests\u2019 BNB locked in the delegator\u2019s unbond queue. Set the number to 0 to get all the locked BNBs.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-the-reward-of-a-delegator","title":"How to get the reward of a delegator?","text":"

    The contracts do not save the initial delegation amount of a delegator. To get the accumulated reward, the following steps can be taken: 1) track the initial delegation amount in your system, 2) call the getPooledBNB of the credit contract of a validator, 3) do the math.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-the-total-staking-address-of-a-validator","title":"How to get the total staking address of a validator?","text":"

    The contract does not provide a function to get the total staking address of a validator. It needs an offchain service to index Delegated, Redelegated, Undelegated events for the purpose.

    "},{"location":"bnb-smart-chain/staking/developer-guide/#how-to-get-all-validators-information","title":"How to get all validators\u2019 information?","text":"

    The StakeHub contract provides the getValidators function to get all validators\u2019 information, including the operator addresses and credit contract addresses.

    To get more information of a specific validator, please refer to the following functions:

    "},{"location":"bnb-smart-chain/staking/overview/","title":"Overview - BSC Staking","text":""},{"location":"bnb-smart-chain/staking/overview/#bsc-staking-overview","title":"BSC Staking Overview","text":"

    BNB Smart Chain (BSC) operates on a Proof-of-Staked-Authority (PoSA) blockchain, with the staking mechanism proposed in BEP-294. This enables BNB holders to stake their tokens with specified validators to secure the network and earn staking rewards. Here\u2019s an overview covering the core staking concepts and operations on BSC.

    "},{"location":"bnb-smart-chain/staking/overview/#basic-concepts","title":"Basic Concepts","text":""},{"location":"bnb-smart-chain/staking/overview/#consensus-engine","title":"Consensus Engine","text":"

    BSC uses a consensus mechanism which combines DPoS and PoA for consensus, in this system:

    The staking mechanism is essential for determining the eligibility of validators to produce blocks.

    "},{"location":"bnb-smart-chain/staking/overview/#validator-set","title":"Validator Set","text":"

    The validator set is the group of nodes that are responsible for validating transactions and producing blocks on the BSC. The validator set is determined by the amount of staking each validator has, which reflects the amount of BNB staked by the validator and its delegators. The top validators with the most staking are selected as the active validator set, and they take turns to propose and vote on blocks. The rest of the validators are in the standby validator set, and they can join the active validator set if their staking increases or if some active validators drop out.

    Any organization or individual can become part of the validator set by creating their validator on-chain and securing sufficient delegations. Similarly, they can opt-out by simply withdrawing all their BNB delegations.

    Validators can also be removed from the validator set by slashing, which is a penalty for misbehaving or being offline.

    "},{"location":"bnb-smart-chain/staking/overview/#validator-election","title":"Validator Election","text":"

    There are different roles for validators:

    The validator set roles are determined every 24 hours based on the latest staking information.

    After UTC 00:00, the consensus engine sorts validators and updates the BSC validator set with the ranking information.

    "},{"location":"bnb-smart-chain/staking/overview/#system-contracts","title":"System Contracts","text":"

    There are several built-in contracts (i.e., system contracts) to facilitate the BSC staking.

    "},{"location":"bnb-smart-chain/staking/overview/#credit-contract","title":"Credit Contract","text":"

    Each validator has its own validator contract that manages staking credit and facilitates the exchange between credit and BNB. The token name of a staking credit is \u201cstake {{validator moniker}} credit\u201d, and the symbol is \u201cst{{validator moniker}}\u201d. The contract will be created by the Stake Hub Contract when a validator is created.

    Whenever a user delegates BNB, an equivalent quantity of credit tokens are created. On the other hand, when a user withdraws their delegation, a corresponding amount of credit tokens are destroyed, thereby releasing the BNB.

    "},{"location":"bnb-smart-chain/staking/overview/#reward-distribution","title":"Reward Distribution","text":"

    The staking reward comes from transaction fee - when a block is produced, the majority of the block fee will be collected as reward for the validator who proposed the block.

    Every day, a portion of the rewards collected will be directly sent to the operator account of the validator as commission, while the remaining portion will be sent to the corresponding validator credit contract. And when a user undelegates and claims his/her stakes, the accumulated reward and the original stake will be sent back to him/her.

    "},{"location":"bnb-smart-chain/staking/overview/#validator-operations","title":"Validator Operations","text":"

    Validators are nodes running BNB Smart Chain software, participating in the consensus process. They require a minimum BNB stake at their validator address and can receive delegations from other BNB holders. Validators earn rewards from transaction fees and share most of these rewards with their delegators.

    "},{"location":"bnb-smart-chain/staking/overview/#create-validator","title":"Create Validator","text":"

    To ensure the security of the network, becoming a validator on the BSC requires a minimum self-delegation of 2000 BNB. BNB holders can initiate a CreateValidator transaction with the StakeHub contract to become a validator. For more information, refer to Create BSC Validator.

    "},{"location":"bnb-smart-chain/staking/overview/#edit-validator","title":"Edit Validator","text":"

    Validators can update their information using transactions like EditConsensusAddress, EditCommissionRate, EditDescription, and EditVoteAddress.

    "},{"location":"bnb-smart-chain/staking/overview/#delegator-operations","title":"Delegator Operations","text":"

    Delegators are BNB holders who stake their BNB with a validator, sharing rewards. They can select any active or standby validator, switch between them, undelegate their BNB, and claim rewards anytime. Users can refer to the user guide for instructions on these actions.

    "},{"location":"bnb-smart-chain/staking/user-guide/","title":"User Guide - BSC Staking","text":""},{"location":"bnb-smart-chain/staking/user-guide/#manage-stakes-with-bnb-staking-dapp","title":"Manage Stakes with BNB Staking dApp","text":"

    Leverage the BNB staking dApp for streamlined management of your stakes. This guide provides a step-by-step walkthrough for using the dApp on both BSC testnet and mainnet.

    "},{"location":"bnb-smart-chain/staking/user-guide/#connect-wallet","title":"Connect Wallet","text":"

    To interact with the dApp, first connect your web3 wallet. Currently, TrustWallet (mainnet only) and MetaMask are supported, along with any wallets compatible with WalletConnect.

    "},{"location":"bnb-smart-chain/staking/user-guide/#delegate-stakes","title":"Delegate Stakes","text":"
    1. Select a validator to delegate your stakes to. Detailed information about each validator is available on their respective pages.
    2. Click the Delegate button to initiate a new delegation.

    3. Enter the amount of BNB you wish to delegate.

    4. After confirming the delegation, your connected wallet will prompt you to sign the transaction. Successful transactions will be visible in the My Staking page, complete with transaction hash.

    "},{"location":"bnb-smart-chain/staking/user-guide/#redelegate-stakes","title":"Redelegate Stakes","text":"

    On the My Staking page, you can manage your existing delegations.

    Note: A redelegation fee of 0.002% applies to discourage frequent switching between validators.

    1. Click Redelegate to shift your stake to a different validator.

    2. In the ensuing popup, select your new validator and specify the amount to redelegate. You can opt to move the entire amount or just a portion.

    "},{"location":"bnb-smart-chain/staking/user-guide/#undelegate-stakes","title":"Undelegate Stakes","text":"

    To claim your stakes and rewards, you need to undelegate.

    1. Click the Undelegate button next to the relevant delegation.

    2. You can choose to undelegate the entire amount or a portion. Note that undelegated stakes are subject to a 7-day unbonding period before they are returned to your account.

    "},{"location":"bnb-smart-chain/staking/user-guide/#claim-stakes","title":"Claim Stakes","text":"

    After the unbonding period, you can claim your stakes by clicking the Claim button.

    "},{"location":"bnb-smart-chain/validator/create-val/","title":"Create BSC Validator - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/create-val/#create-bsc-validator","title":"Create BSC Validator","text":"

    This guide outlines the process for creating a new validator on the BNB Smart Chain (BSC). The BNB staking dApp is the official tool for creating and managing validators on the BSC.

    "},{"location":"bnb-smart-chain/validator/create-val/#terminology","title":"Terminology","text":""},{"location":"bnb-smart-chain/validator/create-val/#steps","title":"Steps","text":""},{"location":"bnb-smart-chain/validator/create-val/#1-connecting-to-the-dapp","title":"1. Connecting to the dApp","text":"

    Please connect to the staking dApp using your Operator Address. Trust Wallet, MetaMask, and WalletConnect options are available for the step. Make sure that the account has more than 2001 BNB before moving on to the next step.

    "},{"location":"bnb-smart-chain/validator/create-val/#2-filling-out-the-form","title":"2. Filling out the form","text":"

    Navigate to the dApp and select the Become a Validator button in the right middle of the page to initiate the creation process.

    The following information is required to create a validator.

    "},{"location":"bnb-smart-chain/validator/create-val/#21-basic-information","title":"2.1 Basic Information","text":"

    You\u2019ll need to provide the following details on the Create Validator page:

    To enhance your validator\u2019s visibility, consider uploading additional information to the BSC validator directory. Your avatar, once uploaded, will be displayed in the staking dApp.

    "},{"location":"bnb-smart-chain/validator/create-val/#22-addresses","title":"2.2 Addresses","text":"

    The following addresses are required:

    "},{"location":"bnb-smart-chain/validator/create-val/#generate-consensus-address","title":"Generate Consensus Address","text":"

    Download the BSC geth binary from the official release page.

    Note: Make sure you are downloading the correct binary based on your machine\u2019s platform, e.g., if you are using MacOS, you should download the geth_mac file. In the following, we will refer the binary as geth for simplicity.

    To create a new account for mining, please use the following command and set a password for the account.

    geth account new --datadir ${DATA_DIR}\n

    This command will provide the public address (consensus address) and the path to your private key. Remember to back up the key file safely! A sample consensus address is 0x4b3FFeDb3470D441448BF18310cAd868Cf0F44B5.

    If you already have an account for mining, you can use the seed phrase to recover the account.

    geth account import --datadir ${DATA_DIR}\n
    "},{"location":"bnb-smart-chain/validator/create-val/#generate-bls-vote-address-and-proof","title":"Generate BLS Vote Address and Proof","text":"

    To create a new bls account please use the following command.

     geth bls account new --datadir ${DATA_DIR}\n

    If you already have a voting key, create a bls wallet and use the keyfile to recover it, using the following command.

     geth bls account import ${KEY_FILE} --datadir ${DATA_DIR}\n

    Then you can get your vote address by running the following command.

    geth bls account list --datadir ${DATA_DIR}\n

    A sample bls address is b5fe571aa1b39e33c2735a184885f737a59ba689177f297cba67da94bea5c23dc71fd4deefe2c0d2d21851eb11081f69.

    Then you can get your bls proof by running the following command.

    geth bls account generate-proof --chain-id ${BSC_CHAIN_ID} ${OPEATOR_ADDRESS} ${VOTE_ADDRESS}\n

    A sample bls proof is 0xaf762123d031984f5a7ae5d46b98208ca31293919570f51ae2f0a03069c5e8d6d47b775faba94d88dbbe591c51c537d718a743b9069e63b698ba1ae15d9f6bf7018684b0a860a46c812716117a59c364e841596c3f0a484ae40a1178130b76a5.

    "},{"location":"bnb-smart-chain/validator/create-val/#create-identity","title":"Create Identity","text":"

    Identity is used to associate the new validator with the old validator created on the BNB Beacon Chain. It should be left empty after the Beacon Chain fusion.

    "},{"location":"bnb-smart-chain/validator/create-val/#23-commissions","title":"2.3 Commissions","text":""},{"location":"bnb-smart-chain/validator/create-val/#24-self-delegation","title":"2.4 Self-delegation","text":""},{"location":"bnb-smart-chain/validator/create-val/#3-submitting-the-form","title":"3. Submitting the form","text":"

    Once you have filled out all the required information, click the Submit button to submit the transaction.

    "},{"location":"bnb-smart-chain/validator/manage-keys/","title":"Key Management for BSC Validator - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/manage-keys/#key-management-for-bsc-validator","title":"Key Management for BSC Validator","text":"

    BEP-294 and BEP-297 introduce the native staking and governance features for BNB Smart Chain (BSC). For a validator, when participating in staking (e.g., creating a validator, self-delegating) and governance, there are several wallet keys that will be involved. To help validators manage their keys and funds effectively and safely, the following practices are recommended.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#operator-key","title":"Operator Key","text":"

    The operator key is used for operating a validator, including creating a validator, editing the information of a validator, and undelegating. When creating a validator, the operator key is also used for self-delegating with more than 2001 BNB. When interacting with the new BSC staking dApp, the operator key is mostly involved.

    Be noted that the operator address can not be changed for a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet. There should be more than 2001 BNB in the operator account when creating a new validator.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#staking-key","title":"Staking Key","text":"

    For a validator, it can also use another key, different from the operator key, to manage his/her delegation if needed. Then, such a staking key will be used to delegate/undelegate/redelegate to different validators and claim rewards. This key could be used frequently, depending on how a validator manages its delegations and rewards.

    Be noted that this key is optional, depending on the needs of a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#consensus-key","title":"Consensus Key","text":"

    The consensus key is used for signing proposed blocks when mining blocks. No fund is needed for this account.

    Recommendation: Use a hot wallet so that it can be easily accessed by a validator node.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#fast-finality-vote-key","title":"Fast Finality Vote Key","text":"

    The fast finality vote key (BLS vote key) is used in the fast finality feature for signing votes of recently mined blocks. No fund is needed for this account.

    Recommendation: Use a hot wallet so that it can be easily accessed by a validator node.

    "},{"location":"bnb-smart-chain/validator/manage-keys/#governance-vote-key","title":"Governance Vote Key","text":"

    The BEP-297 introduces the native BSC staking feature. A delegator (including validators for self-delegation) can delegate someone else to participate in governance on his/her behalf. When there is governance delegation, the governance vote key will be used for casting votes to BSC proposals. The related wallet should store some BNB for gas fees of the voting transaction.

    Be noted that this key is optional, depending on the needs of a validator.

    Recommendation: Use a hardware wallet, a Safe wallet or an MPC wallet.

    "},{"location":"bnb-smart-chain/validator/overview/","title":"BSC Validator Overview - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/overview/#bsc-validator-overview","title":"BSC Validator Overview","text":"

    BNB Smart Chain(BSC) relies on a system of multiple validators with Proof of Staked Authority (PoSA) consensus that can support short block time and lower fees. The most bonded validators in staking will have the opportunity to produce blocks. The double-sign detection and other slashing logics ensure security, stability, and chain finality.

    BSC conducts a daily election process post 00:00 UTC to select the top 45 active validators based on their staking rankings for block production. Among these, the 21 validators with the highest staked amounts are referred to as Cabinets, while the remaining 24 validators are known as Candidates. The remaining inactive validators must wait for the next round of elections to become active validators before they can participate in block production.

    In the set of 45 active validators, each epoch selects 18 validators from the Cabinets and 3 validators from the Candidates, forming a group of 21 validators as the consensus validators set for the current epoch to produce blocks. If a validator is elected as the consensus validator but fails to participate in produce blocks, it will face slashing consequences.

    Cabinets are more likely to be elected as consensus validators for block generation than Candidates, who have a slightly lower probability of being chosen for the same role. However, whether it\u2019s Cabinets or Candidates, if they are not online when it\u2019s their turn to produce a block, they will be slashed. This measure aims to encourage more validators to participate in the consensus, enhancing the decentralization and security of BSC.

    "},{"location":"bnb-smart-chain/validator/overview/#what-is-validator","title":"What is Validator?","text":"

    Validators on the BSC are nodes responsible for producing blocks and securing the network through the POSA consensus mechanism. They participate in packaging transactions, creating and validating blocks to secure the BSC network, earning BNB tokens as rewards in exchange.

    "},{"location":"bnb-smart-chain/validator/overview/#the-network-topology","title":"The Network Topology","text":"

    Validators on the BSC network are interconnected through a peer-to-peer (P2P) network, allowing for both direct and indirect connections. As a validator node operator, you have two operational modes to choose from:

    "},{"location":"bnb-smart-chain/validator/overview/#economics","title":"Economics","text":"

    Validator\u2019s rewards come from transaction fees and commission fees from delegators.

    Let us also assume that the reward for a block is 100 BNB and that a certain validator has 20% of self-bonded BNB and sets its commission rate to 20%. These tokens do not go directly to the proposer. Instead, they are shared among validators and delegators. These 100 BNB will be distributed according to each participant\u2019s stake:

    Commission: 80*20%= 16 BNB\nValidator gets: 100\\*20% + Commission = 36 BNB\nAll delegators get: 100\\*80% - Commission = 64 BNB\n

    The rewards for motivating validators to vote for Fast Finality also comes from transaction fees. The specific rules can refer to BEP126

    If validators double sign, malicious vote or frequently offline, their staked BNB (not including BNB of users that delegated to them) can be slashed. The penalty depends on the severity of the violation.

    You can learn to see the revenue history from BitQuery\u2019s chart or a table of BscScan

    "},{"location":"bnb-smart-chain/validator/overview/#risks-for-validators","title":"Risks for Validators","text":"

    If validators attempt to cheat the system or violate the specifications, they may incur a penalty known as slashing.

    "},{"location":"bnb-smart-chain/validator/overview/#double-sign-slash","title":"Double Sign Slash","text":"

    Running your validator keys simultaneously on two or more machines will result in Double-Sign slashing. The penalty for double-sign slash:

    1. 200 staked BNB will be slashed for the validator.
    2. The double sign jail time is 30 days, preventing the malicious validator from participating in consensus until manual intervention is taken.

    Note: Rewards for submitting double-sign evidence: 5BNB. Anyone can submit a slashing request with the evidence of double sign, which should contain the 2 block headers with the same height and parent block, sealed by the offending validator.

    "},{"location":"bnb-smart-chain/validator/overview/#malicious-fast-finality-vote-slash","title":"Malicious Fast Finality Vote Slash","text":"

    Running your validators with the same consensus keys and bls voting keys concurrently on two or more machines will result in malicious vote slash. The penalty for malicious vote slash:

    1. 200 staked BNB will be slashed for the validator.
    2. The malicious vote jail time is 30 days, you can send an unjail transaction after the jail time to reactivate your validator.

    Note: Rewards for submitting Malicious Vote evidence: 5BNB. Anyone can submit a slash request with the evidence of malicious vote on BSC, which should contain the 2 votes, signed by the offending validator.

    "},{"location":"bnb-smart-chain/validator/overview/#downtime-slash","title":"Downtime Slash","text":"

    If your validator misses over 50 blocks in 24 hours, the blocking reward won\u2019t be given to you but will be shared among other validators. If your validator continues to miss more than 150 blocks within 24 hours, it will trigger the following penalty for being offline.

    1. 10 staked BNB will be slashed for the validator.
    2. The offline jail time is 2 days. This allows the validator to send an unjail transaction and resume as an active validator after 2 days.
    "},{"location":"bnb-smart-chain/validator/overview/#low-self-delegation-slash","title":"Low Self-Delegation Slash","text":"

    Validators must stake a minimum of 2000 BNB for self-delegation. If the self-delegated amount is less, the penalty is 2 days of jail time.

    "},{"location":"bnb-smart-chain/validator/run-val/","title":"Run BSC Validator - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/run-val/#run-bsc-validator","title":"Run BSC Validator","text":""},{"location":"bnb-smart-chain/validator/run-val/#validator-hardware-requirements","title":"Validator Hardware Requirements","text":""},{"location":"bnb-smart-chain/validator/run-val/#mainnet","title":"Mainnet","text":""},{"location":"bnb-smart-chain/validator/run-val/#testnet","title":"Testnet","text":""},{"location":"bnb-smart-chain/validator/run-val/#setup-validator-node","title":"Setup Validator Node","text":""},{"location":"bnb-smart-chain/validator/run-val/#1-install-bsc-fullnode","title":"1. Install BSC Fullnode","text":"

    Follow the instructions here to set up a full node.

    "},{"location":"bnb-smart-chain/validator/run-val/#2-prepare-accounts","title":"2. Prepare Accounts","text":"

    Two accounts require preparation before running a validator: the Consensus account and the BLS Vote account. Ensure these accounts match the corresponding ones when creating a new validator.

    "},{"location":"bnb-smart-chain/validator/run-val/#generate-consensus-address","title":"Generate Consensus Address","text":"

    To create a new mining consensus account, run this command and set a password for the account:

    geth account new --datadir ${DATA_DIR}\n

    If you already have a consensus account, skip this step. Save the password in a file named password.txt:

    echo {your-password for the consensus account} > password.txt\n
    "},{"location":"bnb-smart-chain/validator/run-val/#generate-bls-vote-address","title":"Generate BLS Vote Address","text":"

    To set up a new BLS account, use this command:

    geth bls account new --datadir ${DATA_DIR}\n

    If you already have a BLS vote key, you can create a BLS wallet and recover it with the keyfile using:

    geth bls account import ${KEY_FILE} --datadir ${DATA_DIR}\n

    To retrieve your bls address, run:

    geth bls account list --datadir ${DATA_DIR}\n

    Save the password in a file named blspassword.txt:

    echo {your-password for the BLS wallet} > blspassword.txt\n
    "},{"location":"bnb-smart-chain/validator/run-val/#3-start-validator-node","title":"3. Start Validator Node","text":"

    Warning: Please do not expose your RPC endpoints to public network!

    Start your validator using the command line below:

    geth --config ./config.toml --datadir ./node --syncmode snap -unlock {accounts to sign txs, including your mining account at least} --miner.etherbase {the address of your mining account} --password password.txt --blspassword blspassword.txt --mine --vote --allow-insecure-unlock --cache 18000\n
    "},{"location":"bnb-smart-chain/validator/run-val/#post-running","title":"Post Running","text":""},{"location":"bnb-smart-chain/validator/run-val/#1-monitor-node-status","title":"1. Monitor node status","text":"

    To get started quickly, run GethExporter in a Docker container.

    docker run -it -d -p 9090:9090 \\\n  -e \"GETH=http://mygethserverhere.com:8545\" \\\n  hunterlong/gethexporter\n

    "},{"location":"bnb-smart-chain/validator/run-val/#2-update-validator-profile","title":"2. Update validator profile","text":"

    You can submit a PullRequest to this repository to update your information: https://github.com/bnb-chain/validator-directory

    Reference: https://grafana.com/grafana/dashboards/6976

    "},{"location":"bnb-smart-chain/validator/run-val/#3-publish-validator-information","title":"3. Publish Validator Information","text":"

    Please submit a Pull Request to this repo https://github.com/bnb-chain/bsc-validator-directory

    This repository is a place for validator candidates to give potential delegators a brief introduction about your team and infrastructure, and present your ecosystem contributions.

    "},{"location":"bnb-smart-chain/validator/run-val/#4-stop-validating","title":"4. Stop Validating","text":"

    You can stop mining new blocks by sending commands in geth console

    Connect to your validator node with geth attach ipc:path/to/geth.ipc

    miner.stop()\n

    To resume validating,

    miner.start()\n
    "},{"location":"bnb-smart-chain/validator/run-val/#some-tips-tools","title":"Some Tips & Tools","text":""},{"location":"bnb-smart-chain/validator/run-val/#1run-backup-node","title":"1.Run backup node","text":"

    Backup node could help when your primary validator node encounters issues due to a variety of potential reasons, ensuring the continuity and reliability of your participation in the network.

    "},{"location":"bnb-smart-chain/validator/run-val/#2check-your-nodes-stability","title":"2.Check your node\u2019s stability","text":"

    There is a javascript in BSC repo to dump the slash status of each validator.

    cd <bsc>/cmd/jsutils\n# 1.To dump the slashes of the lates block:\nnode getslashcount.js --Rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce\n\n# 2.You may also specify the block number:\nnode getslashcount.js --Rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce --Num 39938351\n
    If your validator operates smoothly, you should expect minimal or even no penalties, known as \u201cslashes,\u201d on a daily basis. Generally speaking, if your validator incurs more than three slashes within a single day, it would be prudent to investigate the cause for this anomaly."},{"location":"bnb-smart-chain/validator/run-val/#3about-maintenance-mode","title":"3.About maintenance mode","text":"

    Should your validator incur 50 slashes, it will automatically transition into maintenance mode. It is imperative to promptly diagnose and rectify any issues with your node to prevent further penalties. Failure to do so may result in your node being placed in a more restrictive state, often referred to as \u201cjail.\u201d

    Upon successfully restoring your node\u2019s functionality, it is crucial to promptly exit maintenance mode to resume normal operations and avoid any unnecessary downtime or penalties.

    // note: replace \"0x75B851a27D7101438F45fce31816501193239A83\" with your validator's consensus address.\ngeth attach geth.ipc\nweb3.eth.sendTransaction({   from: \"0x75B851a27D7101438F45fce31816501193239A83\",   to: \"0x0000000000000000000000000000000000001000\",   data: \"0x04c4fec6\"})\n
    "},{"location":"bnb-smart-chain/validator/run-val/#4filter-out-peers-by-regex-pattern","title":"4.Filter out peers by regex pattern","text":"

    This functionality was introduced with version 1.4.6, primarily designed to identify and exclude peers that may present operational challenges, thereby preventing connections with them. For further details, please refer to this Pull Request: PR#2404.

    Generally, this feature is not necessary for regular operation. However, in the event that a release contains critical bugs and an immediate upgrade of all nodes to a stable version is not feasible, this feature can be employed to disconnect from peers running the problematic versions. This serves as a temporary solution to mitigate the impact of the bugs until a comprehensive upgrade can be performed.

    For example, if v1.4.9 has known issues, we wanna disconnect nodes of this version, you may update your config.toml and restart:

    [Node.P2P]\nPeerFilterPatterns = [\"Geth/v1.4.9.*\"]\n
    "},{"location":"bnb-smart-chain/validator/security/","title":"Secure BSC Validator - BNB Smart Chain","text":""},{"location":"bnb-smart-chain/validator/security/#secure-bsc-validator","title":"Secure BSC Validator","text":"

    Each BSC validator is encouraged to run its operations independently, as diverse setups increase the resilience of the network. Due to the high amount invested by validators it is highly essential to protect them against different DoS and DDoS attacks. In this section, we discuss the security mechanism adopted by BSC for its validators.

    "},{"location":"bnb-smart-chain/validator/security/#sentry-nodes-ddos-protection","title":"Sentry Nodes (DDOS Protection)","text":"

    Validators should ensure network resilience against denial of service attacks. One effective approach to reduce these risks is by organizing their network in a sentry node architecture. Sentry nodes, easily deployed and capable of IP address changes, operate in private IP space, shielding them from direct internet attacks. This setup guarantees that validator block proposals and votes reliably reach the network.

    To setup your sentry node architecture you can follow the instructions below:

    "},{"location":"bnb-smart-chain/validator/security/#1-setup-nodes","title":"1. Setup Nodes","text":"

    Construct a private network and establish trusted connections between the validator node and its sentry nodes. Refer to the fullnode guide for setting up your validator and sentry nodes. Avoid exposing your validator\u2019s RPC endpoints to the public network.

    "},{"location":"bnb-smart-chain/validator/security/#2-add-peers","title":"2. Add Peers","text":"

    Connect individual sentry nodes\u2019 console, execute admin.nodeInfo.enode command. This will provide you with the enode information for each node, as illustrated below.

    enode://f2da64f49c30a0038bba3391f40805d531510c473ec2bcc7c201631ba003c6f16fa09e03308e48f87d21c0fed1e4e0bc53428047f6dcf34da344d3f5bb69373b@[::]:30306?discport=0\n

    !!! Note: [::] will be interpreted as the localhost (127.0.0.1) address. If your nodes are within a local network, ensure to inspect each host machine to determine its IP using the ifconfig command. However, if your peers are outside the local network, you must be aware of your external IP address to form the enode URL correctly.

    Replace [::] with the correct node URL, copy the enode details, and add them to the config.toml file of the validator node like this:

    # make node hidden\nNoDiscovery = true\n# connect exclusively to sentry\nStaticNodes = [\"enode://f2da64f49c30a0038bba3391f40805d531510c473ec2bcc7c201631ba003c6f16fa09e03308e48f87d21c0fed1e4e0bc53428047f6dcf34da344d3f5bb69373b@[10.1.1.1]:30306\"]\n
    "},{"location":"bnb-smart-chain/validator/security/#3-confirm-connections","title":"3. Confirm Connections","text":"

    Connect to the validator\u2019s console, run admin.peers, and you will see the details of the sentry nodes you added.

    "},{"location":"bnb-smart-chain/validator/security/#firewall-configuration","title":"Firewall Configuration","text":"

    Geth utilizes different ports for various functions.

    It utilizes a listener (TCP) port and a discovery (UDP) port for P2P connections, typically configured to 30303. Ensure this port is open.

    The default JSON-RPC service port is TCP port 8545. To prevent unauthorized admin operations, refrain from exposing the JSON-RPC port externally.

    "},{"location":"bnb-smart-chain/validator/mev/builder-integration/","title":"Integration Guide for Builder - BSC MEV","text":""},{"location":"bnb-smart-chain/validator/mev/builder-integration/#integration-guide-for-builder","title":"Integration Guide for Builder","text":"

    The Builder API Specification defines the standard interface that builders should implement, while the specific implementation is left open to MEV API providers. The BNB Chain community offers a simple implementation example for reference.

    "},{"location":"bnb-smart-chain/validator/mev/builder-integration/#customize-builder","title":"Customize Builder","text":"

    Although the builder offers great flexibility, there are still some essential standards that must be followed:

    1. The builder needs to set up a builder account, which is used to sign the block bid and receive fees. The builder can ask for a tip (builder fee) on the block that it sends to the sentry. If the block is finally selected, the builder account will receive the tip.

    2. The builder needs to implement the mev_reportIssue API to receive the errors report from validators.

    3. In order to prevent transaction leakage, the builder can only send block bids to the in-turn validator.

    4. At most 3 block bids are allowed to be sent at the same height from the same builder.

    Here are some sentry APIs that may interest a builder:

    1. mev_bestBidGasFee. It will return the current most profitable reward that the validator received among all the blocks received from all builders. The reward is calculated as: gasFee*(1 - commissionRate) - tipToBuilder. A builder may compare the bestBidGasFee with a local one and then decide to send the block bid or not.

    2. mev_params. It will return the BidSimulationLeftOver,ValidatorCommission, GasCeil and BidFeeCeil settings on the validator. If the current time is after (except block time - BidSimulationLeftOver), then there is no need to send block bids any more; ValidatorCommission and BidFeeCeil helps the builder to build its fee charge strategy. The GasCeil helps a builder know when to stop adding more transactions.

    Builders have the freedom to define various aspects like pricing models for users, creating intuitive APIs, and define the bundle verification rules.

    "},{"location":"bnb-smart-chain/validator/mev/builder-integration/#setup-with-example-builder","title":"Setup with Example Builder","text":"

    Step 1: Find Validator Information

    For validators that open MEV integration, the public information is shown at bsc-mev-info. Builders can also provide information here to the validator.

    Step 2: Set up Builder.

    The builder must sign the bid using an account, such as the etherbase account specified in the config.toml file.

    [Eth.Miner.Mev]\nBuilderEnabled = true # open bid sending\nBuilderAccount = \"0x...\" # builder address which signs bid, usually it is the same as etherbase address\n

    Configure the validator node list, including the address of the validator and the public URL. The public URL refers to the sentry service.

    [[Eth.Miner.Mev.Validators]]\nAddress = \"0x23707D3D...6455B52B3\"\nURL = \"https://bsc-fuji.io\"\n\n[[Eth.Miner.Mev.Validators]]\nAddress = \"0x52825922...3A1A7A422\"\nURL = \"http://bsc-mathwallet.io\"\n

    Step 3: Publish information

    It is highly recommended to publish information in bsc-mev-info.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/","title":"FAQs - BSC MEV","text":""},{"location":"bnb-smart-chain/validator/mev/faqs/#faqs","title":"FAQs","text":""},{"location":"bnb-smart-chain/validator/mev/faqs/#1-why-is-the-mev-solution-important-for-the-bnb-chain-ecosystem","title":"1. Why is the MEV solution important for the BNB Chain ecosystem?","text":"

    BNB Chain\u2019s MEV solution leverages Proposer Builder Separation (PBS) architecture to foster a more transparent and fair block space market. Through PBS, users gain the power to select their preferred builder for transaction submission, while MEV rewards are equitably distributed among searchers, validators, builders, and BNB stakers. This approach promotes transparency, fairness, user choice, and network security. By distributing rewards across various roles, BNB Chain encourages wider participation and reduces the risk of centralization, to build a decentralized and inclusive blockchain ecosystem.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#2-do-builders-fetch-the-in-turn-proposers-gasceil-to-build-block","title":"2. Do builders fetch the in-turn proposer\u2019s GasCeil to build block\uff1f","text":"

    Yes, you could using RPC mev_params to query validator\u2019s MEV information before building block, it can help to 1) calculate a valid header with gas no more than GasCeil; 2) calculate the left bidding time by BidSimulationLeftOver; 3) calculate suitable builderFee by validatorCommission.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#3-how-does-the-validator-choose-the-best-bid","title":"3. How does the validator choose the best bid?","text":"

    The block reward is calculated as gasFee, the validator reward is calculated as gasFee*commissionRate - builderFee. Every time the validator receives a new bid, it will compare its reward with the existing best bid. If it has better block reward and validator reward, the new bid will go into simulation. If simulation succeeds before block sealing, it will be compared with local mined block reward. If the bid\u2019s block reward and validator reward are both superior to the local block, it will be sealed by the validator.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#4-who-can-become-the-builder","title":"4. Who can become the builder?","text":"

    BNB Chain is a permission-less ecosystem, anyone who implements the standard builder API could be the BNB Chain builder.

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#5-where-can-i-find-the-bnb-chain-builders-information","title":"5. Where can I find the BNB Chain builders information?","text":"

    You can find the BNB Chain builders through a public builder info repo

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#6-how-many-validators-have-been-integrated-with-the-builders","title":"6. How many validators have been integrated with the builders?","text":"

    You can find the validators that has implemented the PBS solution from validator info repo

    "},{"location":"bnb-smart-chain/validator/mev/faqs/#7-where-can-i-find-the-bnb-chain-mev-statistic-dashboard","title":"7. Where can I find the BNB Chain MEV statistic dashboard?","text":"

    You can view the MEV statistics from MEV Stats Dashboard

    "},{"location":"bnb-smart-chain/validator/mev/overview/","title":"Overview - BSC MEV","text":""},{"location":"bnb-smart-chain/validator/mev/overview/#bsc-mev-overview","title":"BSC MEV Overview","text":"

    The BSC network has introduced the Builder API Specification to establish a fair and unified MEV market. Previously, BSC clients lacked native support for validators to integrate with multiple MEV providers at once. The network became unstable because of the many different versions of the client software being used. The latest BSC client adopts the Proposer-Builder Separation model. Within this unified framework, several aspects of the BSC network have been improved:

    "},{"location":"bnb-smart-chain/validator/mev/overview/#what-is-mev-and-pbs","title":"What is MEV and PBS","text":"

    MEV, also known as Maximum (or Miner) Extractable Value, can be described as the measure of total value that may be extracted from transaction ordering. Common examples include arbitraging swaps on decentralized exchanges or identifying opportunities to liquidate DeFi positions. Maximizing MEV requires advanced technical expertise and custom software integrated into regular validators. The returns are likely higher with centralized operators.

    Proposer-builder separation(PBS) solves this problem by reconfiguring the economics of MEV. Block builders create blocks and submit them to the block proposer, and the block proposer simply chooses the most profitable one, paying a fee to the block builder. This means even if a small group of specialized block builders dominate MEV extraction, the reward still goes to any validator on the network.

    "},{"location":"bnb-smart-chain/validator/mev/overview/#how-it-works-on-bsc","title":"How it Works on BSC","text":"

    The figure above illustrates the basic workflow of PBS operating on the BSC network.

    A new component called Sentry has been introduced to enhance network security and account isolation. It assists proposers in communicating with builders and enables payment processing.

    "},{"location":"bnb-smart-chain/validator/mev/overview/#what-is-more","title":"What is More","text":"

    The PBS model on BSC differs in several aspects from its implementation on Ethereum. This is primarily due to\uff1a

    1. Different Trust Model. Validators in the BNB Smart Chain are considered more trustworthy, as it requires substantial BNB delegation and must maintain a high reputation. This stands in contrast to Ethereum, where becoming an Ethereum validator is much easier, the barrier to becoming a validator is very low (i.e., 32 ETH).

    2. Different Consensus Algorithms. In Ethereum, a block header is transferred from a builder to a validator for signing, allowing the block to be broadcasted to the network without disclosing the transactions to the validator. In contrast, in BSC, creating a valid block header requires executing transactions and system contract calls (such as transferring reward and depositing to the validator set contract), making it impossible for builders to propose the whole block.

    3. Different Blocking Time. With a shorter block time of 3 seconds in BSC compared to Ethereum\u2019s 12 seconds, designing for time efficiency becomes crucial.

    These differences have led to different designs on BSC\u2019s PBS regarding payment, interaction, and APIs. For more design philosophy, please refer to BEP322:Builder API Specification for BNB Smart Chain.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/","title":"Integration Guide for Validator - BSC MEV","text":""},{"location":"bnb-smart-chain/validator/mev/validator-integration/#integration-guide-for-validator","title":"Integration Guide for Validator","text":""},{"location":"bnb-smart-chain/validator/mev/validator-integration/#decison-make","title":"Decison Make","text":"

    When activating MEV functionality, validators encounter a mix of opportunities and challenges. Before enabling this feature, validators need to carefully evaluate these risk accordingly:

    1. More maintenance work. Apart from the validator, additional maintenance of the Sentry service and its related network components is required.

    2. Network risk. Due to Sentry service being exposed to the public network, it is inevitably susceptible to possible network attacks.

    3. Financial risk. Validators need to pay fees to builders, securely managing accounts is a crucial topic.

    After identifying these risks, let\u2019s begin the journey.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/#validator-topology","title":"Validator Topology","text":"

    It is suggested that to split the internal network into two part:

    1. Private network. The private network is isolated from the public network. All access to components within this network is strictly restricted. The Validator and Payment wallet are expected to be deployed within a private network environment.

    2. Nat network. The components in this network can communicate with the public internet under certain constraints, and the communication can be established through load balancers provided by various cloud platforms. Sentry service should be deployed within a NAT network environment. It is essential to configure appropriate safeguards on the network gateway to prevent DoS attacks and other potential threats.

    The validator should open its RPC access to the mev-sentry. The mev-sentry should open its RPC to the public network with a domain host. The information of validator should be registered in bsc-mev-info.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/#hardware-spec","title":"Hardware Spec","text":"

    Mev-Sentry: The recommended specifications for the mev-sentry machine are 2 CPUs and 4 GB of RAM.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/#preparation","title":"Preparation","text":"

    The BNB Chain community has maintained an open-source version of the Sentry service. You can clone the code repository from here.

    Before actually deploying the Sentry service, it is crucial to carefully consider and determine several key parameters:

    1. BidFeeCeil. This represents the maximum fee that a validator is willing to pay for a block proposed by a builder. When this value is 0, it signifies that the validator does not accept any charges from the builder.

    2. BidSimulationLeftOver. This parameter indicates how long before the block time the validator should cease simulating the blocks from the builder. It is generally advisable to set it to a few tens of milliseconds. Setting it too small may result in blocks being broadcast too late and subsequently discarded during network congestion.

    It is suggested to purchase a domain that is related to the moniker name of the validator. The builders will send requests through this domain. A BSC account should be created in advance as the payment account. No BNB is required in that account if BidFeeCeil is zero, otherwise, it needs to be ensured that there is enough balance in the account.

    Go to the bsc-mev-info repo to find more information about running builders which will be used during setup.

    "},{"location":"bnb-smart-chain/validator/mev/validator-integration/#quick-setup","title":"Quick Setup","text":"

    Step 1: Setup Sentry.

    Deploy the sentry service according to the readme of sentry repo.

    Here are a few key points to highlight.

    Step 2: Change the Config of Validator.

    Upgrade the validators to version v1.4.x or later, add a few new sections in the config.toml. Example:

      [Eth.Miner.Mev]\n  Enabled = true # open bid receiving\n  ValidatorCommission = 100 # validator claim 1% from block reward\n  BidSimulationLeftOver = 50000000 # 50ms, the time left for bid simulation\n  SentryURL = \"http://bsc-mev-sentry.io\" # it is used for the validator to access the sentry, it should be a private URL or IP:Port.\n\n  # Find builders in [bsc-mev-info](https://github.com/bnb-chain/bsc-mev-info)\n\n  [[Eth.Miner.Mev.Builders]]\n  Address = \"0x45EbEBe8...664D59c12\" # builder address which validator is willing to receive bid from\n\n  [[Eth.Miner.Mev.Builders]]\n  Address = \"0x980A75eC...fc9b863D5\" # builder address which validator is willing to receive bid from\n

    Step 3: Publish information

    It is highly recommended to publish information in bsc-mev-info so other builders can find it.

    "},{"location":"join-ecosystem/","title":"Index","text":"Join BNB Ecosystem There are several ways to share your project with BNB Chain Ecosystem or seeking for cooperations. We want to make it as easy as possible for prjects to get more exposure in BNB Chain Ecosystem or ask for support from the team. Below is the guideline that we ask projects to follow so that we can get achieve this efficiently. DappBay

    Discover top dApps built on BNB Smart Chain, opBNB & BNB Greenfield, the leading blockchain scaling solution.

    Developer Tools

    List your project on the tool page or find the right tools for your development.

    Electrical Capital

    Add your project to BNB ecosystem and contribute on BNB chain developer data

    "},{"location":"join-ecosystem/platforms/dappbay/","title":"Submit Project on DappBay & DappRadar","text":""},{"location":"join-ecosystem/platforms/dappbay/#submit-project-on-dappbay-dappradar","title":"Submit Project on DappBay & DappRadar","text":"

    DappBay & DappRadar are 2 hubs for users to discover top dApps built on BNB Ecosystem. Projects are encouraged to submit dApp informations to them to get full exposure to users.

    Submit to DappBay DappBay currently supports BNB Smart Chain, opBNB and BNB Greenfield. It also provides risk scanning for those dapps to ensure safety for the ecosystem. You can follow below steps to submit your project:

    1. Connect to dappbay with your wallet.
    2. Fill in the form by Clicking on Submit-Dapps.
    3. Submit the updates by repeating steps 1-2 whenever there is a change of your project, including logo, description, github repo, contract address, ect.

    If you find anything to improve, pls contact us on BNB Chain official discord.

    Submit to DappRadar DappRadar is a Dapp Store for user to explore NFTs, NFT Marketplaces, Blockchain Games, De-Fi, Dapps On The Blockchain. It currently supports BNB Smart Chain and opBNB. You can follow below steps to submit your project:

    1. Login DappRadar in the way you prefer.
    2. Fill in the form by Clicking on Submit-Dapp.
    3. Submit the updates by repeating steps 1-2 whenever there is a change of your project, including logo, description, github repo, contract address, ect.
    "},{"location":"join-ecosystem/platforms/dappbay/#submit-project-for-cooperations","title":"Submit Project for Cooperations","text":"

    For projects seeking for cooperations, you could submit your project details in official discord channel submit-project. The team will review your submission and contact you if we find a fit.

    "},{"location":"join-ecosystem/platforms/dev-tool/","title":"Submit Tools on Developers Tool","text":""},{"location":"join-ecosystem/platforms/dev-tool/#submit-tools-on-developers-tool","title":"Submit Tools on Developers Tool","text":"

    Developers Tool is a developer tooling landscape which collects toolings for developers to build on BSC, opBNB and Greenfield. Contributions on this page will make developers find your project and integrate it in their work more easily.

    Steps

    1. Prepare basic information of your project: description, website, logo, supported chain, etc.

    2. Choose the tag (e.g. Defi, AI, Game, etc) and Category (e.g. Wallet, Dex, Marketplace, etc) your project belongs to.

    3. Submit the above information by raising a Github PR here. For more information, please refer to this Guide.

    "},{"location":"join-ecosystem/platforms/electrical-capital/","title":"Contribute on Developer Data","text":""},{"location":"join-ecosystem/platforms/electrical-capital/#contribute-on-developer-data","title":"Contribute on Developer Data","text":"

    To contribute on BNB Chain developer activity, projects should add their github repositories to the community-supported developer tracking tool Crypto Ecosystems, which will track your developer activity and include it in BNB Chain developer statistics.

    Steps

    1. Prepare your github repository.

    2. Create a toml file under ecosystems for your dapp.

    3. Add the created toml file to BNB Chain subecosystem

    4. For more details, please follow this Guide to add your repository to BNB Chain ecosystem. Here is an example for your reference.

    "},{"location":"showcase/game/minigame/","title":"Showcase - Creating Telegram BNB Mini Apps","text":""},{"location":"showcase/game/minigame/#creating-telegram-bnb-mini-apps-a-how-to-guide-for-developers","title":"Creating Telegram BNB Mini Apps: A How-to Guide for Developers","text":"

    Launching decentralized applications on Telegram has become increasingly popular due to it giving users access to mini apps and games without requiring them to install additional software, providing an easy way for users to interact with blockchain-based services. This lowers the barriers to entry for users and makes it simple for developers to distribute their apps to a large Telegram audience.

    This guide will walk you through the steps for building a basic Telegram mini app on BNB in just a few hours. By the end, you will have the skills to launch your own BNB project on Telegram\u2019s open platform. Whether you are a blockchain expert or just starting out, this tutorial aims to demystify decentralized app creation. So let\u2019s get started building on BSC! The possibilities are endless when you master Telegram mini apps.

    Note: This guide only provides a high level overview of the steps that may be involved in creating telegram BNB miniapp. For a detailed guide, visit the youtube demo or the github repo.

    "},{"location":"showcase/game/minigame/#introduction-to-telegram-bnb-mini-apps","title":"Introduction to Telegram BNB Mini Apps","text":""},{"location":"showcase/game/minigame/#what-are-telegram-mini-apps","title":"What are Telegram Mini Apps?","text":"

    Telegram Mini Apps are lightweight web apps that run inside Telegram chats. They allow developers to create social experiences, games, marketplaces, and other services that tap into Telegram\u2019s features and large audience.

    Catizen\u2019s play-to-earn and Hamster Kombat\u2019s tap-to-earn, what\u2019s the next big thing for Telegram mini games?

    Mini Apps load instantly, work offline, and don\u2019t need to be installed. They can use Telegram login, payments, storage and more. Developers can build Mini Apps using HTML, CSS and JavaScript. How to Create a Mini App To create a Mini App, you need:

    Your web app will run in an iframe and communicate with the user\u2019s Telegram app using the Telegram Bridge. The Bridge exposes the Telegram API and passes messages between your web app and the user\u2019s Telegram app.

    "},{"location":"showcase/game/minigame/#mini-app-types","title":"Mini App Types","text":"

    There are two main types of Mini Apps:

    "},{"location":"showcase/game/minigame/#inline-apps","title":"Inline Apps","text":"

    Inline Apps show up as results when a user types the bot\u2019s username followed by a query. The user taps an app result to launch the Mini App. Inline Apps are great for:

    "},{"location":"showcase/game/minigame/#direct-link-apps","title":"Direct Link Apps","text":"

    Users can open a Direct Link App just by tapping a link. Direct Link Apps are aware of the current chat context and support shared, collaborative experiences. Direct Link Apps are ideal for:

    The mini app can also be launched from a keyboard button, from an inline button, and from the bot menu button. Refer to the official Telegram mini app documentation.

    "},{"location":"showcase/game/minigame/#step-by-step-guide-to-creating-a-bnb-mini-app","title":"Step-by-Step Guide to Creating a BNB Mini App","text":"

    With the power of Telegram behind them, Mini Apps open up countless new opportunities for creativity and building engaging experiences on the platform. The potential for Mini Apps is huge, and this is just the beginning.

    "},{"location":"showcase/game/minigame/#create-a-telegram-bot","title":"Create a Telegram Bot","text":"

    To get started, you will need to create a Telegram bot. Visit the @BotFather bot and enter /newbot to create a new bot. You will receive an API token for your bot. Keep this token private as it will allow you to control your bot.

    "},{"location":"showcase/game/minigame/#connect-the-webapp-to-your-bot","title":"Connect the Webapp to Your Bot","text":"

    Next, you need to connect your webapp to the Telegram bot. Use the /newapp command in the @BotFather bot by selecting your bot. Provide details such as the app name, description, photo, etc. Finally, enter the URL of your webapp. Your mini app will now appear in the Telegram app and can be launched by users.

    "},{"location":"showcase/game/minigame/#additional-capabilities","title":"Additional Capabilities","text":"

    Mini apps opened from a direct link have limited capabilities. They cannot read or send messages on behalf of the user. However, they support cooperative and multiplayer features within the current chat context. Users must redirect to inline mode to actively pick a result in order to send messages.

    Mini apps are powerful tools for creating fully-fledged web services, team collaborations, multiplayer games, and more. The possibilities are endless.

    "},{"location":"showcase/game/minigame/#turning-your-mini-app-into-a-game","title":"Turning Your Mini App Into a Game","text":"

    To transform your Mini App into an engaging game on Telegram, you must first register a bot with @BotFather and create a Mini App as outlined in the previous section. Once you have a functioning Mini App, you can then convert it into a game by using Telegram\u2019s Game API.

    "},{"location":"showcase/game/minigame/#difference-between-mini-apps-and-mini-games","title":"Difference Between Mini Apps and Mini Games","text":"

    Mini games build upon mini apps by providing additional information like:

    To create a mini game, use the /newgame command and configure callback functions to return your game\u2019s URL.

    "},{"location":"showcase/game/minigame/#register-a-game-with-gamebot","title":"Register a Game with @GameBot","text":"

    The first step is to register your game with @BotFather. Send the /newgame command to @BotFather, and provide the required details including:

    Implement Callbacks You must implement callback functions in your code to handle interactions with the Telegram Game API. Specifically, you need a callback_query() callback which will receive updates from Telegram when a user clicks an inline button in your game. Within this callback, you should check the callback ID to determine which button was clicked. You may implement multiple inline keyboard buttons for the game, but note that the first button must always launch the game.

    "},{"location":"showcase/game/minigame/#share-your-game","title":"Share Your Game","text":"

    Once registered, your game will receive a shareable game URL and a game code which players can enter to launch the game. You can share this URL and code on your website, social media, and within Telegram chats to spread your game to new players.

    "},{"location":"showcase/game/minigame/#consider-a-leaderboard-optional","title":"Consider a Leaderboard (Optional)","text":"

    To increase engagement and competition, you can implement an in-game leaderboard where players can see the top scores. You will need to store player scores in a database, and return the leaderboard data within your callbacks. Leaderboards are an optional feature, but can greatly enhance the popularity and longevity of Telegram games.

    By following these steps, you can build fully-featured games within Telegram using JavaScript and the Telegram Game API. Games are an exciting way to engage users, and the possibilities for multiplayer, social, and interactive gaming experiences on Telegram are endless. Let your creativity run wild, and build the next hit game on Telegram!

    "},{"location":"showcase/game/minigame/#faqs-about-telegram-bnb-mini-apps","title":"FAQs About Telegram BNB Mini Apps","text":""},{"location":"showcase/game/minigame/#what-are-the-main-features-of-telegram-bnb-mini-apps","title":"What are the main features of Telegram BNB Mini Apps?","text":"

    Telegram BNB Mini Apps allow developers to build decentralized applications on BSC or opBNB that can be accessed directly within Telegram. Some of the key features include:

    "},{"location":"showcase/game/minigame/#what-are-the-differences-between-mini-apps-and-bots","title":"What are the differences between Mini Apps and Bots?","text":"

    Telegram Mini Apps are web apps that run within the Telegram app, while Telegram Bots are automated accounts controlled via API. Some key differences include:

    "},{"location":"showcase/game/minigame/#what-languages-and-frameworks-can-i-use-to-build-a-mini-app","title":"What languages and frameworks can I use to build a Mini App?","text":"

    You can build Telegram Mini Apps using:

    "},{"location":"showcase/game/minigame/#summary","title":"Summary","text":"

    Telegram mini apps and mini games provide developers with exciting new ways to engage users. By following the step-by-step guide outlined here, you can leverage Telegram\u2019s massive user base to share your own interactive web apps and games. Consider the possibilities - multiplayer experiences, chatbots, productivity tools and more are now just a few lines of code away. As Telegram continues expanding its platform, developers have an opportunity to be on the cutting edge and reach an audience of millions. So don\u2019t wait, get started building your own mini app today! With the right idea and a bit of effort, you could create the next viral sensation on Telegram.

    "},{"location":"showcase/identity/attestation-dev/","title":"Get Started - Attestation","text":""},{"location":"showcase/identity/attestation-dev/#get-started-attestation","title":"Get Started - Attestation","text":""},{"location":"showcase/identity/attestation-dev/#creating-on-chain-attestations","title":"Creating On-chain Attestations","text":"

    The attest function enables you to confidently create an on-chain attestation for a specific schema. This powerful function accepts an object with the following properties:

    This function gracefully returns a Promise that resolves to the UID of the newly created attestation.

    import { BAS, SchemaEncoder } from \"@bnb-attestation-service/bas-sdk\";\n\nconst bas = new BAS(BASContractAddress);\nbas.connect(signer);\n\n// Initialize SchemaEncoder with the schema string\nconst schemaEncoder = new SchemaEncoder(\"uint256 eventId, uint8 voteIndex\");\nconst encodedData = schemaEncoder.encodeData([\n  { name: \"eventId\", value: 1, type: \"uint256\" },\n  { name: \"voteIndex\", value: 1, type: \"uint8\" },\n]);\n\nconst schemaUID = \"0xb16fa048b0d597f5a821747eba64efa4762ee5143e9a80600d0005386edfc995\";\n\nconst tx = await bas.attest({\n  schema: schemaUID,\n  data: {\n    recipient: \"0xFD50b031E778fAb33DfD2Fc3Ca66a1EeF0652165\",\n    expirationTime: 0,\n    revocable: true,// Be aware that if your schema is not revocable, this MUST be false\n    data: encodedData,\n  },\n});\n\nconst newAttestationUID = await tx.wait();\n\nconsole.log(\"New attestation UID:\", newAttestationUID);\n
    "},{"location":"showcase/identity/attestation-dev/#creating-off-chain-attestations-without-saving-to-greenfield","title":"Creating Off-chain Attestations without Saving to GreenField","text":"

    To generate an off-chain attestation, you can confidently utilize the signOffchainAttestation function offered by the Off-chain class in the BAS SDK. Here\u2019s an example:

    import { SchemaEncoder } from \"@bnb-attestation-service/bas-sdk\";\n\nconst offchain = await bas.getOffchain();\n\n// Initialize SchemaEncoder with the schema string\nconst schemaEncoder = new SchemaEncoder(\"uint256 eventId, uint8 voteIndex\");\nconst encodedData = schemaEncoder.encodeData([\n  { name: \"eventId\", value: 1, type: \"uint256\" },\n  { name: \"voteIndex\", value: 1, type: \"uint8\" },\n]);\n\n// Signer is an ethers.js Signer instance\nconst signer = new ethers.Wallet(privateKey, provider);\n\nconst offchainAttestation = await offchain.signOffchainAttestation({\n  recipient: '0xFD50b031E778fAb33DfD2Fc3Ca66a1EeF0652165',\n// Unix timestamp of when attestation expires. (0 for no expiration)\n  expirationTime: 0,\n// Unix timestamp of current time\n  time: 1671219636,\n  revocable: true,// Be aware that if your schema is not revocable, this MUST be false\n  version: 1,\n  nonce: 0,\n  schema: \"0xb16fa048b0d597f5a821747eba64efa4762ee5143e9a80600d0005386edfc995\",\n  refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n  data: encodedData,\n}, signer);\n\nThis function will confidently generate an attestation object off-chain, which will be signed and contain the UID, signature, and attestation data. You can confidently share this object with the intended recipient or confidently store it for future use.\n
    "},{"location":"showcase/identity/attestation-dev/#creating-off-chain-attestation-and-saving-to-greenfield","title":"Creating Off-chain Attestation and Saving to GreenField","text":"

    To generate an off-chain attestation and save the result to GreenField Storage, you can confidently utilize the attestOffChain function offered by the BAS SDK. Here\u2019s an example:

      const offchain = await bas.getOffchain();\n\n  // Use wallet or client to ensure the chain is BNB\n  // [WARN]: should call an async function\n  await shouldSwitchNetwork(chains[1].id); // BNB chainId\n\n  // Attest offchain\n  const attestation = await attestOffChain({\n    schemaStr: attestParams.schemaStr,\n    schemaUID: attestParams.schemaUID,\n    data: attestParams.data,\n    recipient: attestParams.recipient,\n    revocable: attestParams.revocable,\n  });\n\n  const attestationUID = attestation.uid;\n\n  // Use wallet or client to ensure the chain is Greenfield Chain\n  await shouldSwitchNetwork(chains[0].id);\n  const provider = await connector?.getProvider({ chainId: chains[0].id });\n\n  BigInt.prototype.toJSON = function () {\n    return this.toString();\n  };\n\n  // Encode the attestation object into blob to store on the Greenfield Storage\n  const str = JSON.stringify(attestation);\n  const bytes = new TextEncoder().encode(str);\n  const blob = new Blob([bytes], {\n    type: \"application/json;charset=utf-8\",\n  });\n\n  let res;\n  try {\n    // Use GreenField SDK to store the attestation\n    res = await gfClient.createObject(\n      provider,\n      new File([blob], `${attestParams.schemaUID}.${attestationUID}`),\n      attestParams.isPrivate || true\n    );\n  } catch (err: any) {\n    console.log(err);\n    alert(err.message);\n  }\n

    This function will generate an attestation object off-chain. The attestation object will be signed and will contain the UID, signature, and attestation data. Similar to the previous function, you can also save it to greenfield storage and set the access according to your preferences.

    "},{"location":"showcase/identity/attestation-dev/#more-use-cases","title":"More Use Cases","text":"

    On-chain attestations will enable a powerful new range of web3 applications, including:

    And many more!

    "},{"location":"showcase/identity/attestation-dev/#resources","title":"Resources","text":""},{"location":"showcase/identity/attestation/","title":"Showcase - BNB Attestation Service","text":""},{"location":"showcase/identity/attestation/#bnb-attestation-service","title":"BNB Attestation Service","text":""},{"location":"showcase/identity/attestation/#what-is-attestation","title":"What is attestation?","text":"

    Attestations are digital signatures on structured data used to build more trust on-chain.

    "},{"location":"showcase/identity/attestation/#bnb-attestation-servicebas","title":"BNB Attestation Service(BAS)","text":"

    The BNB Attestation Service (BAS) is an infrastructure built on the BNB ecosystem for generating attestation to verify information. BAS assists users in on-chain or off-chain verification, allowing them to assert ownership of attestation by storing them in Greenfield. This approach ensures data privacy and access control.

    BAS serves as a standard and infrastructure for generating arbitrary attestations. Anyone can define any attestation in BAS along with its resolver. BAS supports the generation of on-chain/off-chain attestations, and by storing off-chain attestations in Greenfield, users gain ownership, ensure attestation privacy, and implement access control.

    "},{"location":"showcase/identity/attestation/#core-components-of-bas","title":"Core Components of BAS","text":"

    Checkout the smart contracts here.

    "},{"location":"showcase/identity/attestation/#types-of-attestations","title":"Types of attestations","text":"

    Attestations can be made either onchain or offchain. While onchain attestations are stored directly on the BNBChain, offchain attestations reside outside of it, often in decentralized storage solutions like Greenfield. Both methods have their unique advantages, and the choice largely depends on the specific requirements of the use case.

    Learn about the idfference between on-chain and off-chain difference here.

    "},{"location":"showcase/identity/attestation/#on-chain-attestation-record","title":"On-Chain Attestation Record","text":"

    Users can clearly view the structure of an on-chain attestation on BASCAN.

    "},{"location":"showcase/identity/attestation/#offchain-attestation-record","title":"OffChain Attestation Record","text":"

    Here\u2019s an off-chain attestation record. Unlike the on-chain record, this attestation is public, and the server is unaware of it. Users can share the attestation URL with others to decode the data or publish it to GreenField. Once published or pinned to GreenField, the status icon will switch to \u201cpublic.\u201d

    "},{"location":"showcase/identity/attestation/#use-cases-of-attestation","title":"Use Cases of Attestation","text":""},{"location":"showcase/identity/attestation/#kyc","title":"KYC","text":"

    Combined BAS with zero-knowledge proofs, zkPass uses three-party TLS and zero-knowledge (ZK) technology to create zero-knowledge proofs of user\u2019s real-world assets or actions directly in your browser. This ensures privacy by not oversharing your data and not requiring API authorizations. ZKPass is a private data protocol using affordable zero-knowledge technology. You can learn more about the use case in this blog.

    "},{"location":"showcase/identity/attestation/#developer-on-chain-reputation","title":"Developer on-chain reputation","text":"

    Aspecta ID integrates with the BAS to create and verify on-chain attestations of developers\u2019 achievements and activities, ensuring transparency, security, and trust in digital identity management. This partnership allows Aspecta to offer a tamper-proof and verifiable record of developers\u2019 skills and contributions, enhancing interoperability and trust within the AI and blockchain ecosystems. By leveraging BAS, Aspecta provides developers with a robust platform to authenticate their credentials, making their professional profiles more credible and secure. You can learn more about the use case in this blog.

    "},{"location":"showcase/identity/did/","title":"Showcase - Decentralized Identity","text":""},{"location":"showcase/identity/did/#decentralized-identity","title":"Decentralized Identity","text":""},{"location":"showcase/identity/did/#what-is-decentralized-identity","title":"What is Decentralized Identity?","text":"

    Identity, in both the digital and physical worlds, serves as a means of distinguishing and authenticating individuals and entities.

    Digital Identity:

    Decentralized Identifier (DID):

    "},{"location":"showcase/identity/did/#how-are-decentralized-identities-secured","title":"How are decentralized identities secured?","text":"

    A crucial aspect of securing decentralized identities is cryptography. In cryptography, private keys are known only to their owners, while public keys are widely distributed. This pairing serves two main purposes. First, it enables authentication, allowing the public key to verify that a message was sent by the holder of the corresponding private key. Second, it facilitates encryption, ensuring that only the holder of the paired private key can decrypt a message encrypted with the public key.

    "},{"location":"showcase/identity/did/#benefits-of-decentralized-identity","title":"Benefits of decentralized identity","text":""},{"location":"showcase/identity/did/#decentralized-identity-use-cases","title":"Decentralized Identity Use Cases","text":"Industry Traditional Process Problems/Risks Verifiable Credentials Solution Supply chain Utilizes physical IDs and documents to prove compliance, leading to inefficiencies. Documents can be easily falsified and are challenging to authenticate. The manual verification process is slow and error-prone. Unapproved and non-compliant medical supplies can enter the market, endangering public health. Verifiable Credentials are tamper-proof and can be verified instantly without needing to contact the issuer, greatly reducing time and costs. Finance To access financial services, individuals must undergo compliance screening by submitting personal details in physical form, which are stored in large databases and shared with multiple third parties for KYC and credit checks. Individuals have no control over the security, sharing, and access of their data by third parties. Credentials are cryptographically secured, tamper-proof, and can be verified, ensuring data integrity and security. Healthcare Employers manually verify paper-based licenses and certificates for healthcare providers. Traditional verification processes take weeks or months, delaying the filling of essential healthcare positions. Medical licenses can be issued as digital credentials by regulatory organizations, allowing healthcare providers to easily share them for immediate verification by hospitals, clinics, or medical departments where they seek employment."},{"location":"showcase/identity/dns-dev/","title":"Get Started - SpaceID","text":""},{"location":"showcase/identity/dns-dev/#get-started-spaceid","title":"Get Started - SpaceID","text":""},{"location":"showcase/identity/dns-dev/#how-to-resolve-a-name-using-the-space-id-sdk","title":"How to Resolve a Name Using the Space ID SDK","text":""},{"location":"showcase/identity/dns-dev/#step-1-setup-your-project","title":"Step 1: Setup Your Project","text":"
    1. Install Node.js and npm Ensure you have Node.js and npm installed. You can download them from Node.js official website.

    2. Create a New Project Open your terminal and create a new project directory:

    mkdir spaceid-tutorial\ncd spaceid-tutorial\nnpm init -y\n
    3. Install the Space ID SDK Install the Space ID SDK package using npm:
    Copy code\nnpm install @spaceid/sdk\n
    "},{"location":"showcase/identity/dns-dev/#step-2-write-the-code-to-resolve-a-name","title":"Step 2: Write the Code to Resolve a Name","text":"
    1. Create a JavaScript File Create a file named resolveName.js in your project directory.

    2. Import the Space ID SDK At the top of resolveName.js, import the Space ID SDK:

    const { SpaceID } = require('@spaceid/sdk');\n
    3. Initialize the Space ID SDK Initialize the SDK with the necessary parameters:
    const spaceId = new SpaceID({\n    endpoint: 'https://api.spaceid.io', // API endpoint\n    apiKey: 'your_api_key' // Replace with your actual API key\n});\n
    1. Resolve a Name Write a function to resolve a name using the SDK:
    async function resolveName(name) {\n    try {\n        const result = await spaceId.resolveName(name);\n        console.log(`Address for ${name}: ${result.address}`);\n    } catch (error) {\n        console.error('Error resolving name:', error);\n    }\n}\n
    1. Call the Function Call the resolveName function with a sample name:
    resolveName('example.eth');\n
    "},{"location":"showcase/identity/dns-dev/#step-3-run-the-code","title":"Step 3: Run the Code","text":"
    1. Run the Script In your terminal, run the script:
    node resolveName.js\n
    2. View the Result If everything is set up correctly, you should see the resolved address for the provided name in the terminal output."},{"location":"showcase/identity/dns-dev/#example-code","title":"Example Code","text":"

    Here\u2019s the complete code for resolveName.js:

    const { SpaceID } = require('@spaceid/sdk');\n\nconst spaceId = new SpaceID({\n    endpoint: 'https://api.spaceid.io',\n    apiKey: 'your_api_key'\n});\n\nasync function resolveName(name) {\n    try {\n        const result = await spaceId.resolveName(name);\n        console.log(`Address for ${name}: ${result.address}`);\n    } catch (error) {\n        console.error('Error resolving name:', error);\n    }\n}\n\nresolveName('example.eth');\n
    Replace \u2018your_api_key\u2019 with your actual API key and \u2018example.eth\u2019 with the name you want to resolve. You can read more in this blog."},{"location":"showcase/identity/dns/","title":"Showcase - Decentralized Naming Service","text":""},{"location":"showcase/identity/dns/#decentralized-naming-service","title":"Decentralized Naming Service","text":""},{"location":"showcase/identity/dns/#traditional-dns-vs-decentralized-naming-service","title":"Traditional DNS vs Decentralized Naming Service","text":"

    Traditional Domain Name System (DNS) and decentralized naming services like Ethereum Name Service (ENS) serve similar purposes but differ significantly in their underlying structures and control mechanisms. Traditional DNS translates human-readable domain names into IP addresses, enabling users to access websites easily. It is managed by centralized authorities, such as ICANN, which oversee the domain registration and resolution process. This centralization can lead to vulnerabilities, such as censorship, single points of failure, and control by a few entities.

    In contrast, decentralized naming services like ENS operate on blockchain technology, distributing control among network participants. ENS maps human-readable names to Ethereum addresses and other resources using smart contracts, ensuring that no single entity has overarching control. This decentralized approach enhances security, reduces the risk of censorship, and provides greater resilience against failures, aligning with the principles of trustlessness and user sovereignty inherent in blockchain ecosystems.

    "},{"location":"showcase/identity/dns/#spaceid","title":"SpaceID","text":""},{"location":"showcase/identity/dns/#overview","title":"Overview","text":"

    Space ID offers a universal namespace for blockchain, enabling users to register and manage domain names across different blockchains. It enhances cross-chain interoperability and simplifies user identification across the Web3 ecosystem. This project supports a broad range of applications, from crypto trading to token lending and NFT minting, showcasing a versatile approach to decentralized digital identities.

    "},{"location":"showcase/identity/dns/#how-spaceid-works","title":"How SpaceID works","text":"

    SPACE ID aims to create a universal name service network that connects decentralized identities with the physical and digital worlds. It is progressing toward becoming a comprehensive digital identity solution for Web3. Read the details here

    "},{"location":"showcase/identity/dns/#key-features-of-spaceid","title":"Key features of SpaceID","text":"

    Multi-Chain Name Service

    Among the top priorities of SPACE ID is supporting more blockchains and top-level domains (TLDs). Unlike SPACE ID 1.0, whose main emphasis was on .bnb Name Service, SPACE ID 2.0 instead focuses on multi-chain name service. SPACE ID has reached out to various blockchains for partnership discussions, and expects its ecosystem to flourish with time.

    Web3 Name SDK & API

    SPACE ID aims to streamline web3 services through the use of a single SDK to assist in the building of DApps. This saves developers time, since they don\u2019t have to work with multiple protocols and be encumbered with issues of blockchain incompatibility. This vision is being realized by adding an all-in-one API over the SDK, allowing current and future partners to seamlessly integrate their web3 services with their unified Web3 Name SDK.

    "},{"location":"showcase/identity/dns/#benefits-of-dns","title":"Benefits of DNS","text":""},{"location":"showcase/identity/dns/#use-case-of-spaceid","title":"Use Case of SpaceID","text":""},{"location":"showcase/wallet/in-app-wallet/","title":"Showcase - Thirdweb Wallet SDK Solution","text":""},{"location":"showcase/wallet/in-app-wallet/#service-plan","title":"Service plan","text":"

    Developers can choose between two service plans tailored to their needs:

    1. Free Plan: Offers basic functionalities and limited access to Thirdweb services.
    2. Pro Plan: Provides advanced features, priority support, and expanded usage limits.

    "},{"location":"showcase/wallet/in-app-wallet/#sdk-key-creation","title":"SDK Key Creation","text":"

    To utilize Thirdweb services, developers need to create an SDK key. This key allows integration of the Thirdweb SDK into their applications, enabling various blockchain functionalities.

    "},{"location":"showcase/wallet/in-app-wallet/#services-of-thirdweb","title":"Services of Thirdweb","text":"

    1. Storage Service

    2. In-App Wallet (Wallet as a Service)

    3. Account Abstraction

    4. Third-Party Bundler and Paymaster Integration

    "},{"location":"showcase/wallet/in-app-wallet/#supported-chains","title":"Supported Chains","text":"Chain mainnet testnet BSC Y Y opBNB Y N"},{"location":"showcase/wallet/in-app-wallet/#typical-example-in-react-app","title":"Typical example in React app","text":"

    https://portal.thirdweb.com/connect/account-abstraction/guides/react

    "},{"location":"zkbnb/","title":"zkBNB","text":"zkBNB

    zkBNB is the launchpad to achieve infinite scaling for all things Web3 and GameFi. It offers incredible scalability, Layer-1 level security, and frictionless developer experience to build dApps that can onboard the next billion users.

    Architecture

    zkBNB is a zero-knowledge scalability solution

    Resources

    Providing a Wealth of Resources for Building zkBNB

    "},{"location":"zkbnb/overview/","title":"zkBNB Overview - zkBNB","text":""},{"location":"zkbnb/overview/#what-is-zkbnb","title":"What is zkBNB?","text":"

    The zkBNB is an infrastructure for developers that helps them to build large scale BSC-based apps with higher throughput and much lower or even zero transaction fees.

    zkBNB is built on zk-Rollup architecture. zkBNB bundle (or \u201croll-up\u201d) hundreds of transactions off-chain and generates cryptographic proof. These proofs can come in the form of SNARKs (succinct non-interactive argument of knowledge) which can prove the validity of every single transaction in the Rollup Block.

    "},{"location":"zkbnb/overview/#problems-zkbnb-solves","title":"Problems zkBNB solves","text":"

    Today BSC is experiencing network scalability problems and the core developer has proposed to use sidechains in their Outlook 2022 paper to solve this problem because these sidechains can be designed for much higher throughput and lower gas fees.

    The BEP100 propose a modular framework for creating BSC-compatible side chains and connect them by native relayer hub. The security of native relayer hub is guaranteed by the side chain.

    According to the analysis of chainalysis, bridges are now a top target for the hackers and attacks on bridges account for 69% of total funds stolen in 2022. zkBNB can perfectly solve the problem! Thanks to zkSNARK proofs, zkBNB share the same security as BSC does.

    "},{"location":"zkbnb/overview/#what-are-the-key-features-of-zkbnb","title":"What are the key features of zkBNB?","text":"

    BNB achieves the following goals:

    (BEP721 token must be created in zkBNB in order to transfer from L1 to L2)

    Note: Full Exit and Exodus Exit are two different types of functionalities on zkBNB. Full exit is just about user can click a button and withdraw all his assets in one go. Exodus exit is about in emergency situation, say the whole zkBNB is down, user can still withdraw all this assets.

    "},{"location":"zkbnb/resources/","title":"Resources - zkBNB","text":""},{"location":"zkbnb/resources/#resources","title":"Resources","text":""},{"location":"zkbnb/resources/#repos","title":"\ud83d\udcd4 Repos","text":""},{"location":"zkbnb/resources/#building-dapps-on-zkbnb","title":"\ud83d\udc68\u200d\ud83d\udd27 Building Dapps on zkBNB","text":"

    Start building dapps to create value based on the data assets and their related economy. - Fund your zkBNB Wallet (Coming Soon\u23f0) - Build a dapp with zkBNB API (Coming Soon\u23f0)

    "},{"location":"zkbnb/resources/#help-support","title":"\ud83d\ude4b\u200d\u2640\ufe0f Help & Support","text":"

    Check out the zkBNB Developer Discord for technical support. (TBA \ud83d\udce2)

    "},{"location":"zkbnb/core-concept/overview/","title":"Overview - zkBNB Core Concepts","text":""},{"location":"zkbnb/core-concept/overview/#key-features","title":"Key Features","text":""},{"location":"zkbnb/core-concept/overview/#digital-asset-management","title":"Digital Asset Management","text":"

    The zkBNB will serve as an alternative marketplace for issuing, using, paying and exchanging digital assets in a decentralized manner. zkBNB and BSC share the same token universe for BNB, BEP2 and NFT tokens. This defines: - The same token can circulate on both networks, and flow between them bi-directionally via L1 <> L2 communication. - The total circulation of the same token should be managed across the two networks, i.e. the total effective supply of a token should be the sum of the token\u2019s total effective supply on both BSC and BC. - The tokens can only be initially created on BSC in BEP20, then pegged to the zkBNB. It is permissionless to peg token onto zkBNB.

    User can deposit, transfer, and withdraw both non-fungible token and fungible token on zkBNB.

    Users enter the zk-rollup by depositing tokens in the rollup\u2019s contract deployed on the BSC. The zkBNB monitor will track deposits and submit it as a layer2 transaction, once committer verifies the transaction, users get funds on their account, they can start transacting by sending transactions to the committer for processing.

    User can transfer any amount of funds to any existed accounts on zkBNB by sending a signed transaction to the network.

    Withdrawing from zkBNB to BSC is straightforward. The user initiates the withdrawal transaction, the fund will be burned on zkBNB. Once the transaction in the next batch been rolluped, a related amount of token will be unlocked from rollup contract to target account.

    "},{"location":"zkbnb/core-concept/overview/#nft-management-and-marketplace","title":"NFT Management and Marketplace","text":"

    We target to provide an opensource NFT marketplace for users to browse, buy, sell or create their own NFT. The meta-data of NFT on zkBNB sticks to the BSC standard. The ERC721 standard NFT can be seamlessly deposited on zkBNB, or in reverse.

    Above diagram shows the framework of Nft Marketplace and zkBNB. All the buy/sell offer, meta-data of NFT/Collection, medium resources, account profiles are store in the backend of NFT marketplace, only the contendHash, ownership, creatorTreasuryRate and few other fields are recorded on zkBNB. To encourage price discovery, anyone can place buy/sell offer in the marketplace without paying any fees since the offer is cached in the backend instead of being sent to the zkBNB. Once the offer is matched, an AtomicMatch transaction that consist of buy and sell offer will be sent to zkBNB to make the trade happen. Users can also cancel an offer manually by sending a cancel offer transaction to disable the backend cached offer.

    "},{"location":"zkbnb/core-concept/overview/#seamless-l1-wallet-management","title":"Seamless L1 Wallet Management","text":"

    zkBNB natively supports ECDSA signatures and follows EIP712 signing structure, which means most of the Ethereum wallets can seamless support zkBNB. There is no extra effort for BSC users to leverage zkBNB.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/","title":"zkBNB Architecture - zkBNB","text":""},{"location":"zkbnb/core-concept/zkbnb-arch/#zkbnb-architecture","title":"zkBNB Architecture","text":"

    zkBNB is a zero-knowledge scalability solution, or L2, which focuses on straightforward token operations and built-in marketplaces for Gaming and Social use cases. It serves as a scalability solution for the BNB Smart Chain by bundling multiple transactions into a single transaction, reducing costs for on-chain transactions. The Zero Knowledge proof system used in zkBNB ensures a much faster finality time of the L2 transactions, that helps improve the user experience. zkBNB is essentially built on the zk-Rollup architecture.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#zk-rollup-architecture","title":"zk-Rollup Architecture","text":""},{"location":"zkbnb/core-concept/zkbnb-arch/#maximum-throughput","title":"Maximum throughput","text":"

    Pending benchmark\u2026

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#data-availability","title":"Data Availability","text":"

    zkBNB publish state data for every transaction processed off-chain to BSC. With this data, it is possible for individuals or businesses to reproduce the rollup\u2019s state and validate the chain themselves. BSC makes this data available to all participants of the network as calldata.

    zkBNB don\u2019t need to publish much transaction data on-chain because validity proofs already verify the authenticity of state transitions. Nevertheless, storing data on-chain is still important because it allows permissionless, independent verification of the L2 chain\u2019s state which in turn allows anyone to submit batches of transactions, preventing malicious committer from censoring or freezing the chain.

    zkBNB will provide a default client to replay all state on Layer2 based on these call data.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#transaction-finality","title":"Transaction Finality","text":"

    BSC acts as a settlement layer for zkBNB: L2 transactions are finalized only if the L1 contract accepts the validity proof and execute the txs. This eliminates the risk of malicious operators corrupting the chain (e.g., stealing rollup funds) since every transaction must be approved on Mainnet. Also, BSC guarantees that user operations cannot be reversed once finalized on L1.

    zkBNB provides relative fast finality speed within 10 minutes.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#instant-confirmation-zkbs","title":"Instant confirmation ZkBS","text":"

    Even though time to finality is about 10 minutes, it does not affect the usability of the network. The state transition happens immediately once the block been proposed on zkBNB. The rollup operations are totally transparent to most users, users can make further transfers without waiting.

    "},{"location":"zkbnb/core-concept/zkbnb-arch/#censorship-resistance","title":"Censorship resistance","text":"

    Committer will execute transactions, produce batches. While this ensures efficiency, it increases the risk of censorship :malicious zk-rollup committer can censor users by refusing to include their transactions in batches.

    As a security measure, zkBNB allow users to submit transactions directly to the rollup contract on Mainnet if they think they are being censored by the operator. This allows users to force an exit from the zk-rollup to BSC without having to rely on the commiter\u2019s permission.

    "}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index dbc3dde7a2..633123a3a6 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,947 +2,947 @@ https://docs.bnbchain.org/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/feynman-bsc/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/final-sunset-bc-testnet/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/haber-bsc/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/haber-opbnb/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/mongolian-greenfield/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/second-sunset-bc-testnet/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/second-sunset-bc/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/announce/veld-greenfield/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/developers/crosschain-redelegation/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/developers/gov/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/developers/staking/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/developers/system-contracts/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/owners/bind/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/owners/liquidity-check/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/post-fusion/faq/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/post-fusion/merkle-tree-verify/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/post-fusion/token-recovery/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/users/assets/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/users/bep153-stake-migration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/users/gov/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/users/new-stake/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/users/stake-migration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/users/swaps/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/users/timelocks/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/validators/creation/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/validators/gov/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/validators/key-management/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/validators/migrations/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/validators/slash/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bc-fusion/validators/staking/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/introduction/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/core-concept/accounts/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/core-concept/billing-payment/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/core-concept/bnb-token-model/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/core-concept/programmability/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/core-concept/data-storage/data-availability/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/core-concept/data-storage/data-storage/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/core-concept/data-storage/simple-storage-service/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/bundle-service/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/get-started-dev/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/interact-node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/apis-and-sdks/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/apis-and-sdks/sdk-go/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/apis-and-sdks/sdk-js/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/cross-chain-integration/contract-list/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/cross-chain-integration/dapp-integration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/cross-chain-integration/demo-contract-as-bucket-owner/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/cross-chain-integration/interface/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/cross-chain-integration/mirror-concept/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/cross-chain-integration/mirror/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/cross-chain-integration/mirroring-faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/data-archive/blob-hub/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/data-archive/block-hub/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/data-archive/data-archive-layer/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/data-archive/light-peer/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/network-endpoint/endpoints/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/network-endpoint/network-info/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/file-management-overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/hosting-websites-overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/transitioning-from-s3-to-greenfield/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/access-control/access-control/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/access-control/cmd-access-control/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-cmd/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/access-control/cross-chain-access-control-by-sdk/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/app/data-marketplace/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/app/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/app/file-management/basic-file-management/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/app/file-management/batch-upload/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/app/file-management/js-file-managemet/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-developers/tutorials/app/file-management/resumable-upload/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-validator/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-validator/run-node/become-validator/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-validator/run-node/run-challenger/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-validator/run-node/run-node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/for-validator/run-node/run-relayer/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/getting-started/dcellar/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/getting-started/general-faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/getting-started/get-test-bnb/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/getting-started/greenfield-command/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/getting-started/token-transfer/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/getting-started/wallet-configuration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/roadmap/features/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/roadmap/roadmap/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/standard/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/storage-provider-lifecycle/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/common-issues/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/compile-dependences/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/config/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/exit-SP-network/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/join-SP-network/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/piece-store/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/run-SP-node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/run-local-SP-network/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-greenfield/storage-provider/run-book/sp-faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/advanced/full-stack-dapp/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/advanced/local-dev-env/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/advanced/local-node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/advanced/node-best-practices/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/advanced/reth-node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/advanced/run-with-pebbledb-and-pbss/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/advanced/verify-on-opbnbscan/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/core-concepts/account-abstraction-on-opbnb/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/core-concepts/gas-and-fees/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/core-concepts/opbnb-metrics/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/core-concepts/opbnb-protocol-addresses/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/core-concepts/optimisations-on-opstack/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/core-concepts/raas/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/core-concepts/why-bsc-requires-opbnb/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/core-concepts/why-opstack/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/developers/bep20-crosschain/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/developers/cheat-sheet/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/developers/developer-tools/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/developers/geth-sync/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/developers/multisig-wallet/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/developers/network-faucet/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/developers/quick-guide/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/developers/set-gas-price/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/faq/build-on-opbnb-faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/faq/cross-chain-faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/faq/gas-and-fees-faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/faq/opbnb-bridge-faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/faq/protocol-faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/get-started/deposit-to-opbnb/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/get-started/network-info/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/get-started/wallet-configuration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-opbnb/get-started/withdraw-from-opbnb/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/introduction/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/faucet/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/quick-guide/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/rpc/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/wallet-configuration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/archive_node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/boot_node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/docker/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/fast_node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/full_node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/node_best_practices/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/node_maintenance/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/reth_node/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/upgrade_geth/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/paymaster/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/paymaster/paymaster-api/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/developers/paymaster/wallet-integration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/governance/apis/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/governance/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/governance/temp-check/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/governance/user-guide/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/slashing/monitor/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/slashing/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/slashing/slash-rules/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/staking/developer-guide/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/staking/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/staking/user-guide/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/create-val/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/manage-keys/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/run-val/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/security/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/mev/builder-integration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/mev/faqs/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/mev/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/bnb-smart-chain/validator/mev/validator-integration/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/join-ecosystem/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/join-ecosystem/platforms/dappbay/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/join-ecosystem/platforms/dev-tool/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/join-ecosystem/platforms/electrical-capital/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/showcase/game/minigame/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/showcase/identity/attestation-dev/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/showcase/identity/attestation/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/showcase/identity/did/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/showcase/identity/dns-dev/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/showcase/identity/dns/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/showcase/wallet/in-app-wallet/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/zkbnb/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/zkbnb/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/zkbnb/resources/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/zkbnb/core-concept/overview/ - 2024-08-09 + 2024-08-13 daily https://docs.bnbchain.org/zkbnb/core-concept/zkbnb-arch/ - 2024-08-09 + 2024-08-13 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 128132b02e..d824a0f27f 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ