Skip to content

Instantly share code, notes, and snippets.

@devonwesley
Created January 12, 2018 02:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devonwesley/de70cda80bd015d55909d00c4613ff4e to your computer and use it in GitHub Desktop.
Save devonwesley/de70cda80bd015d55909d00c4613ff4e to your computer and use it in GitHub Desktop.
The deployment section of the app.
  1. Install the Ganache Blockchain:
$ npm install --global ganache-cli
  1. 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"))
}
  1. Display an account:
<div class="mui-col-md-6">
  <div class="mui-panel">
    <div id="account-addresses"></div>
  </div>
</div>
  1. Get accounts from the Ganache Chain with Web3:
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')
}
  1. 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')
      )
    })
  })
}
  1. 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))
}
  1. 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'
  }
}
  1. 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))
    }  
  })
}
  1. 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))
  )
}
  1. 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
}
  1. 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
}
  1. 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)
}
  1. 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  
}
  1. The deploy contract event method in action:
deployContractEvent(contractName, contract)
  1. Contract function section:
<section id="contractFunction" class="mui-container"></section>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment