- Install the
Ganache Blockchain
:
$ npm install --global ganache-cli
- Get a
Web3
instance:
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider)
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
}
- Display an account:
<div class="mui-col-md-6">
<div class="mui-panel">
<div id="account-addresses"></div>
</div>
</div>
- Get accounts from the
Ganache Chain
withWeb3
:
function getAccounts() {
const ethAccount = web3.eth.accounts[0]
return document
.getElementById('account-addresses')
.innerHTML = `<div>
Account: ${ethAccount}
<br />
Balance: ${balanceInEth(ethAccount)}
</div>
`
}
function balanceInEth(address) {
return web3.fromWei(web3.eth.getBalance(address).toString(), 'ether')
}
- Adding a deploy button to each contract
function renderContractList() {
const contractListContainer = document.getElementById('contract-list')
const { contracts } = compiledContract
Object.keys(contracts).forEach((contract, index) => {
const label = `contract-id-${contract}-${Math.random()}`
const gas = contracts[contract].gasEstimates.creation
createContractInfo(gas, contract, label, function (el) {
contractListContainer.appendChild(el)
const btnContainer = document.getElementById(label)
btnContainer.appendChild(
buttonFactory('primary', contract, contracts[contract], 'details')
)
btnContainer.appendChild(
buttonFactory('danger', contract, contracts[contract], 'deploy')
)
})
})
}
- The deploy contract event
function deployContractEvent(name, contract) {
const comfirmMsg = `
Contract: ${name.substring(1)}
Network: ${currentNetwork()}
Confirm to deploy with these settings.
`
if (!confirm(comfirmMsg)) return
const { bytecode, interface } = contract
const newContract = web3.eth.contract(JSON.parse(interface))
const options = { from: web3.eth.accounts[0], data: bytecode, gas: 1000000 }
newContract.new(options, newContractCallback(name))
}
- Contract callback:
function currentNetwork() {
const network = web3.eth.getBlock(0).hash
const main = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'
const test = '0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d'
switch (network) {
case main:
return 'Main Net'
case test:
return 'Ropsten Network'
default:
return 'TestRPC Testnet'
}
}
- Render a contract:
function renderContract(contract, contractName) {
status(`Contract Deployed...`)
const { transactionHash, address } = contract
web3.eth.getTransaction(transactionHash, (err, transaction) => {
if (!err) {
const props = { ...transaction, ...contract, }
const details = {
blockNumber: transaction.blockNumber,
contractName,
address,
}
createContractPanel(details, panel => createContract(props, panel))
}
})
}
- Displaying the contract:
function createContractPanel(contract, callback) {
const div = document.createElement('DIV')
div.className = 'mui-panel'
div.innerHTML = `
<h3>
<strong>Contract: </strong>
${contract.contractName}
</h3>
<p>
<strong>Block Number: </strong>
${contract.blockNumber}
</p>
<p>
<strong>Contract Balance: </strong>
${balanceInEth(contract.address)}
</p>
<strong>Contract Address: </strong>
${contract.address}
</p>
`
callback(div)
}
10.Create the contract:
function createContract(contract, panel) {
const propHandler = lists => props => {
if(!filterProps(props[0])) {
const container = categorizeContractProps({
key: props[0],
value: props[1],
...lists
})
container.append(createContractElement(props, container))
}
}
createPropsContainers(panel, lists => Object
.entries(contract)
.forEach(propHandler(lists))
)
}
- Contract panel:
function createPropsContainers(panel, callback) {
document.getElementById('contractFunction').appendChild(panel)
const propsList = createPanelContainer('props')
const hashList = createPanelContainer('hashes')
const functionList = createPanelContainer()
const banner = '<H3><strong>Contract Functions: </strong></H3>'
functionList.innerHTML = banner
panel.append(propsList)
panel.append(hashList)
panel.append(functionList)
callback({ propsList, hashList, functionList })
}
function createPanelContainer(label) {
const notProp = label !== 'props' || label !== 'hashes'
const el = notProp ? 'UL' : 'DIV'
const key = notProp ? 'listStyleType' : 'marginLeft'
const list = document.createElement(el)
list.className = notProp ? 'mui-row' : 'mui-panel'
list.style[key] = notProp ? 'none' : 0
return list
}
- Catorgorize contract props:
function categorizeContractProps(params) {
const hashNames = {
'hash': 'hash',
'blockHash': 'blockHash',
'input': 'input',
'from': 'from',
}
if (hashNames[params.key]) {
return params.hashList
}
if (typeof params.value === 'function') {
return params.functionList
}
return params.propsList
}
- Contract Elements:
function createContractElement(contractProp, container) {
return typeof contractProp[1] === 'function'
? createContractFunction(contractProp, container)
: createContractProp(contractProp, 'P')
}
function createContractFunction(contractFunc, container) {
const name = contractFunc[0]
const func = contractFunc[1]
const btn = document.createElement('BUTTON')
btn.className = 'mui-btn mui-btn--primary mui-col-md-2'
btn.innerText = name
const eventHandler = () => {
const div = document.createElement('DIV')
div.className = 'mui-col-md-3'
div.innerHTML = `<br /> "${func()}"`
container.appendChild(div)
}
btn.addEventListener('click', eventHandler)
return btn
}
function createContractProp(contractProp, element) {
const className = 'mui-col-md-2 mui-panel'
const name = contractProp[0]
const value = contractProp[1]
const hashesNames = {
'hash': 'hash',
'blockHash': 'blockHash',
'input': 'input',
'from': 'from',
}
return hashesNames[name]
? createContractHash(name, value, 'LI')
: createContractHash(name, value, 'P', className)
}
- Create contract hash:
function createContractHash(name, hash, tag, className) {
const el = document.createElement(tag)
const value = name === 'input'
? `<br/><textarea style="width: 100%;">${hash}</textarea>`
: hash
el.className = className
el.innerHTML = `<br/><strong>${name}</strong>: ${value}`
return el
}
- The deploy contract event method in action:
deployContractEvent(contractName, contract)
- Contract function section:
<section id="contractFunction" class="mui-container"></section>