--- title: "Vinu_validator" date: 2023-11-13T15:23:16+07:00 draft: true --- ## 依赖 版本: opera v1.1.2-rc3 - golang1.19.3.linux-amd64.tar.gz - gcc (for go-duktape) ## 先决条件 - Minimum 200,000$VC, 15x self-stake amount. - m5.xlarge(4 CPUs 16GB RAM) 500GB SSD - Unlock period: 30days from when undelegate(bonding time) ## 只读节点 - 下载 genesis file ```shell # mainnet curl https://vinu-blockchain-mainnet-genesis.s3.us-east-1.amazonaws.com/vitainu-genesis-mainnet-with-contracts.g --output vitainu-genesis-mainnet-with-contracts.g # testnet curl https://vinu-blockchain-genesis.s3.us-east-1.amazonaws.com/vitainu-genesis-testnet.g --output vitainu-genesis-testnet.g ``` - 启动 ```shell # mainnet nohup ./opera --port 3000 --nat any --genesis ./GENESIS_FILENAME.g \ --bootnodes enode://105ecea3fafaa01a329b9ce988d69ad7d9af233b04ad2c3b637b2f42862623c38f358bd7a7cfead5ae61991681965629abe2749131168bdd9ce573f8085380ab@node-0.vinuchain-rpc.com:3000 \ > opera.log & # testnet nohup ./opera --port 3000 --nat any --genesis ./GENESIS_FILENAME.g --genesis.allowExperimental --bootnodes enode://c7e3e7ab29d1ee7693a11d1a6d019db543f71c428b0f323f082e9d13d10cc2d6cc11cdb1dd27e21746afeb0c48435d0f55ad01c2b89162fdac0d0f7c2f4744d0@54.203.151.219:3000 > opera.log & ``` ## Validator - Create validator wallet(validator's identity) ```shell opera account new # Enter wallet password ``` - Fund wallet 200,000$VS + - Create a new Validator key ```shell opera validator new # Enter validator key password ``` - Create validator ```shell # attach opera console opera attach # initialize the SFC contract ABI variable (https://github.com/VinuChain/VinuChain): abi = JSON.parse (https://pastebin.com/sbDq7T92) abi = JSON.parse("[{\"anonym…able\",\"type\":\"function\"}]") # initialize the SFC contract object itself sfcc = web3.vc.contract(abi).at("0xfc00face00000000000000000000000000000000") // Sanity check sfcc.lastValidatorID() // if everything is all right, will return a non-zero value # Get your validator id sfcc.getValidatorID("VALIDATOR_WALLET_ADDRESS") # Unlock validator wallet personal.unlockAccount("VALIDATOR_WALLET_ADDRESS", "PASSWORD", 300) ``` - Register validator ```shell # Register your validator tx = sfcc.createValidator("0xYOUR_PUBKEY", {from:"0xYOUR_WALLET_ADDRESS", value: web3.toWei("200000.0", "vc")}) // 200000.0 VC # Check your registration transaction vc.getTransactionReceipt(tx) # Get your validator id sfcc.getValidatorID("VALIDATOR_WALLET_ADDRESS") ``` - Run validator node ```shell # stop the opera process pkill opera sudo killall opera ## # mainnet nohup ./opera --bootnodes enode://105ecea3fafaa01a329b9ce988d69ad7d9af233b04ad2c3b637b2f42862623c38f358bd7a7cfead5ae61991681965629abe2749131168bdd9ce573f8085380ab@node-0.vinuchain-rpc.com:3000 --validator.id ID --validator.pubkey VALIDATOR_PUBKEY --validator.password PATH_TO_PASSWORDFILE > validator.log & # testnet nohup ./opera --bootnodes enode://c7e3e7ab29d1ee7693a11d1a6d019db543f71c428b0f323f082e9d13d10cc2d6cc11cdb1dd27e21746afeb0c48435d0f55ad01c2b89162fdac0d0f7c2f4744d0@54.203.151.219:3000 --validator.id ID --validator.pubkey VALIDATOR_PUBKEY --validator.password PATH_TO_PASSWORDFILE > validator.log & ``` ## 更新 Validator 节点信息 - Host the config file somewhere publicly accessible ```json { "name": "VALIDATOR_NAME", /* Name of the validator */ "logoUrl": "LOGO_URL", /* Validator logo (PNG|JPEG|SVG) - 100px x 100px is enough */ "website": "WEBSITE_URL", /* Website icon on the right */ "contact": "CONTACT_URL" /* Contact icon on the right */ } ``` - Open up a go-opera console session ```shell opera attach ``` - Load the `stakerInfoContract` ABI and instantiate the contract ```js abi = JSON.parse('[{"inputs":[{"internalType":"address","name":"_stakerContractAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"stakerID","type":"uint256"}],"name":"InfoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakerInfos","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_stakerContractAddress","type":"address"}],"name":"updateStakerContractAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_configUrl","type":"string"}],"name":"updateInfo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_stakerID","type":"uint256"}],"name":"getInfo","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]') # mainnet stakerInfoContract = web3.vc.contract(abi).at("0xb914a0b16111BaB228ae6214e6E1FD4a5EaE877C") # testnet stakerInfoContract = web3.vc.contract(abi).at("0x6b39bcd174DddF5A17d065822BDC43353eB6112A") ``` - Call the updateInfo function of the stakerInfoContract (make sure you have enough VC on your wallet to cover the transaction fee) ```js # Unlock validator wallet personal.unlockAccount("VALIDATOR_WALLET_ADDRESS", "PASSWORD", 300) # stakerInfoContract.updateInfo("CONFIG_URL", { from: "VALIDATOR_WALLET_ADDRESS" }) # Validate if you updated your info correctly stakerInfoContract.getInfo(STAKER_ID) ``` ## 赎回 ## API 节点