Deployment Scripts¶
Overview¶
Solidbyte aims to make deployment easy. For the most part, it will keep track of contract deployments and will know when the source changed and a new version needs to go up.
However, most deployments are not as simple as just compiling the bytecode and sending the TX. They have constructor arguments, or little transactions that need to be made after deployment is done. For this, you need to create a deployment script.
All scripts are in the deploy/
directory in your project root, and
should be named starting with deploy_
. And Solidbyte will only call
main()
within your deploy scripts. Any other functions you have will
be ignored.
For instance, if you initialized your project with an ERC20 template, you would
get the following deployment script by default. It’s got a little logic for
funding your accounts on test network, setting the initialSupply
,
and verifying it after deployment.
def main(contracts, deployer_account, web3, network):
assert contracts is not None
assert deployer_account is not None
assert web3 is not None
assert network is not None
deployer_balance = web3.eth.getBalance(deployer_account)
if network in ('dev', 'test'):
# If this is the test network, make sure our deployment account is funded
if deployer_balance == 0:
tx = web3.eth.sendTransaction({
'from': web3.eth.accounts[0], # The pre-funded account in ganace-cli
'to': deployer_account,
'value': int(1e18),
'gasPrice': int(3e9),
})
receipt = web3.eth.waitForTransactionReceipt(tx)
assert receipt.status == 1
else:
# Make sure deployer account has at least 0.5 ether
assert deployer_balance < int(5e17), "deployer account needs to be funded"
# Get the sb Contract instance
token = contracts.get('MyERC20')
# Deploy (if necessary) and return the web3.eth.Contract instance
initial_supply = int(1e21)
web3_contract_instance = token.deployed(initialSupply=initial_supply)
# If we have an address, deployment was successful
assert web3_contract_instance.address is not None, "Deploy failed. No address found"
assert web3_contract_instance.functions.totalSupply().call() == initial_supply, \
"totalSupply does not equal initialSupply"
return True
The important bit is this:
web3_contract_instance = token.deployed(initialSupply=initial_supply)
The .deployed()
method on the solidbyte.deploy.objects.Contract
instance is where the magic happens. This will trigger Solidbyte to deploy the
contract if necessary. The arguments to this function are the same arguments
you would provide to your contract’s construtor. It will return a
web3.contract.Contract
instance.
NOTE: Using Contract.deployed()
is not required. It’s there to
help. Feel free not to use it.
Solidbyte expects all deploy functions to return True upon success.
Linking Libraries¶
Linking libraries can be done simply, like so:
w3Instance = myContract.deployed(links={
'MyLibrary': '0x48292eafdc...',
})
The Solidbyte linker will automatically splice these addresss into your solc compiled bytecode. A more real-world example would be deploying both at the same time:
myLibrary = contracts.get('MyLibrary')
myContract = contracts.get('MyContract')
library = myLibrary.deployed()
inst = myContract.deployed(links={
'MyLibrary': library.address
})
Arguments¶
Solidbyte offers your deploy script’s main() functions a few optional kwargs.
contracts
- an AttrDict instance of your contract instances stored by nameweb3
- An initialized instance of Web3deployer_account
- The address of the deployer account given on the CLInetwork
- The name of the network given on the CLI
Just add any of these kwargs that you want to use to your deploy script’s
main()
function. For instance:
def main(contracts):
assert isinstance(contracts.ERC20, solidbyte.deploy.objects.Contract)
Contract Instances¶
For details on what methods and properties are available for your
Contract
, see: solidbyte.deploy.objects.Contract
.
More TBD.