Skip to content

Instantly share code, notes, and snippets.

@libotony
Last active February 18, 2019 10:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save libotony/f33a4cbcf3948866dfc579f86d526aee to your computer and use it in GitHub Desktop.
Save libotony/f33a4cbcf3948866dfc579f86d526aee to your computer and use it in GitHub Desktop.
Setup your own VeChain Thor network

Requirements

  1. At least one MasterNode
  2. At least one Rich Account
  3. At least two public nodes that can connect each other
  4. Executor Can be an address or Executor Contract(Vote contract among steering committee)

Configure Steps

Here we change genesis/testnet.go, this will allow us to build a network with peer to peer network. Furthermore you can change genesis/devnet.go to run a dev-net in solo mode, this allows you to do test locally.

LaunchTime

We can set the network to launch in the future.

launchTime := uint64(1530014400) // 'Tue Jun 26 2018 20:00:00 GMT+0800 (CST)'

Set Account Balance

// 50 billion for richAccount
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(50*1000*1000*1000))
state.SetBalance(richAccount, amount)
state.SetEnergy(richAccount, &big.Int{}, launchTime)

Setup BuiltIn Contracts

Authority

Setup contract code:

state.SetCode(builtin.Authority.Address, builtin.Authority.RuntimeBytecodes())

Set endorsor's balance (Not required):

state.SetBalance(endorsorAddress, thor.InitialProposerEndorsement)
state.SetEnergy(endorsorAddress, &big.Int{}, launchTime)

Note: Must update energy when touching account's balance in genesis

Add MasterNode:

data := mustEncodeInput(builtin.Authority.ABI, "add", anode.masterAddress, anode.endorsorAddress, anode.identity)
builder.Call(tx.NewClause(&builtin.Authority.Address).WithData(data), executorAddress)

Energy

Setup contract code:

state.SetCode(builtin.Energy.Address, builtin.Energy.RuntimeBytecodes())

Set total supply:

builtin.Energy.Native(state, launchTime).SetInitialSupply(tokenSupply, energySupply)

Extension

Setup contract code:

state.SetCode(builtin.Extension.Address, builtin.Extension.RuntimeBytecodes())

Params

Setup contract code:

state.SetCode(builtin.Params.Address, builtin.Params.RuntimeBytecodes())

Initiate Params:

// Set executor
data := mustEncodeInput(builtin.Params.ABI, "set", thor.KeyExecutorAddress, new(big.Int).SetBytes(executorAddress[:]))
builder.Call(tx.NewClause(&builtin.Params.Address).WithData(data), thor.Address{})
// Set energy reward ratio
data = mustEncodeInput(builtin.Params.ABI, "set", thor.KeyRewardRatio, thor.InitialRewardRatio)
builder.Call(tx.NewClause(&builtin.Params.Address).WithData(data), executorAddress)
// Set base gas price
data = mustEncodeInput(builtin.Params.ABI, "set", thor.KeyBaseGasPrice, thor.InitialBaseGasPrice)
builder.Call(tx.NewClause(&builtin.Params.Address).WithData(data), executorAddress)
// Set proposer endorsement
data = mustEncodeInput(builtin.Params.ABI, "set", thor.KeyProposerEndorsement, thor.InitialProposerEndorsement)
builder.Call(tx.NewClause(&builtin.Params.Address).WithData(data), executorAddress)

Prototype

Setup contract code:

state.SetCode(builtin.Prototype.Address, builtin.Prototype.RuntimeBytecodes())

Executor

If your executor is an Address, you just need to set the address when initiating Params contract.

// Set executor
data := mustEncodeInput(builtin.Params.ABI, "set", thor.KeyExecutorAddress, new(big.Int).SetBytes(executorAddress[:]))
builder.Call(tx.NewClause(&builtin.Params.Address).WithData(data), thor.Address{})

If your executor is an Executor Contract, you need to set contract code and approvers.

Setup contract code:

state.SetCode(builtin.Executor.Address, builtin.Executor.RuntimeBytecodes())

Set executor address in Params Contract:

data := mustEncodeInput(builtin.Params.ABI, "set", thor.KeyExecutorAddress, new(big.Int).SetBytes(builtin.Executor.Address[:]))
builder.Call(tx.NewClause(&builtin.Params.Address).WithData(data), thor.Address{})

Add approvers in Executor Contract:

data := mustEncodeInput(builtin.Executor.ABI, "addApprover", approver.address, thor.BytesToBytes32([]byte(approver.identity)))
builder.Call(tx.NewClause(&builtin.Executor.Address).WithData(data), executorAddress)

Steps

  1. Craft genesis
  2. make thor
  3. Start MasterNode with thor -network test
  4. Wait for the launch time, master will propose blocks
// Copyright (c) 2018 The VeChainThor developers
// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>
package genesis
import (
"math/big"
"github.com/vechain/thor/builtin"
"github.com/vechain/thor/state"
"github.com/vechain/thor/thor"
"github.com/vechain/thor/tx"
"github.com/vechain/thor/vm"
)
// NewTestnet create genesis for testnet.
func NewTestnet() *Genesis {
launchTime := uint64(1530014400) // 'Tue Jun 26 2018 20:00:00 GMT+0800 (CST)'
acccount0, _ := thor.ParseAddress("0xe59D475Abe695c7f67a8a2321f33A856B0B4c71d")
master0, _ := thor.ParseAddress("0x25AE0ef84dA4a76D5a1DFE80D3789C2c46FeE30a")
endorser0, _ := thor.ParseAddress("0xb4094c25f86d628fdD571Afc4077f0d0196afB48")
approver0 := acccount0
builder := new(Builder).
Timestamp(launchTime).
GasLimit(thor.InitialGasLimit).
State(func(state *state.State) error {
tokenSupply := new(big.Int)
// alloc precompiled contracts
for addr := range vm.PrecompiledContractsByzantium {
state.SetCode(thor.Address(addr), emptyRuntimeBytecode)
}
// setup builtin contracts
state.SetCode(builtin.Authority.Address, builtin.Authority.RuntimeBytecodes())
state.SetCode(builtin.Energy.Address, builtin.Energy.RuntimeBytecodes())
state.SetCode(builtin.Executor.Address, builtin.Executor.RuntimeBytecodes())
state.SetCode(builtin.Params.Address, builtin.Params.RuntimeBytecodes())
state.SetCode(builtin.Prototype.Address, builtin.Prototype.RuntimeBytecodes())
state.SetCode(builtin.Extension.Address, builtin.Extension.RuntimeBytecodes())
// 50 billion for account0
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(50*1000*1000*1000))
state.SetBalance(acccount0, amount)
state.SetEnergy(acccount0, &big.Int{}, launchTime)
tokenSupply.Add(tokenSupply, amount)
// 25 million for endorser0
amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(25*1000*1000))
state.SetBalance(endorser0, amount)
state.SetEnergy(endorser0, &big.Int{}, launchTime)
tokenSupply.Add(tokenSupply, amount)
builtin.Energy.Native(state, launchTime).SetInitialSupply(tokenSupply, &big.Int{})
return nil
}).
// set initial params
Call(
tx.NewClause(&builtin.Params.Address).WithData(mustEncodeInput(builtin.Params.ABI, "set", thor.KeyExecutorAddress, new(big.Int).SetBytes(builtin.Executor.Address[:]))),
thor.Address{}).
Call(
tx.NewClause(&builtin.Params.Address).WithData(mustEncodeInput(builtin.Params.ABI, "set", thor.KeyRewardRatio, thor.InitialRewardRatio)),
builtin.Executor.Address).
Call(
tx.NewClause(&builtin.Params.Address).WithData(mustEncodeInput(builtin.Params.ABI, "set", thor.KeyBaseGasPrice, thor.InitialBaseGasPrice)),
builtin.Executor.Address).
Call(
tx.NewClause(&builtin.Params.Address).WithData(mustEncodeInput(builtin.Params.ABI, "set", thor.KeyProposerEndorsement, thor.InitialProposerEndorsement)),
builtin.Executor.Address).
// add master0 as the initial block proposer
Call(tx.NewClause(&builtin.Authority.Address).WithData(mustEncodeInput(builtin.Authority.ABI, "add", master0, endorser0, thor.BytesToBytes32([]byte("master0")))),
builtin.Executor.Address).
// add approver
Call(tx.NewClause(&builtin.Executor.Address).WithData(mustEncodeInput(builtin.Executor.ABI, "addApprover", approver0, thor.BytesToBytes32([]byte("Sunny Lu")))),
builtin.Executor.Address)
id, err := builder.ComputeID()
if err != nil {
panic(err)
}
return &Genesis{builder, id, "testnet"}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment