Giter Site home page Giter Site logo

augesco's Introduction

Augesco

Live Example

Augesco is a new ethereum dapp development framework that is intended to provide more out-of-the-box functionality for truffle-based projects. The project is similar to drizzle which is provided by truffle. A large problem I found with drizzle and generally developing web dapps is the large amount of boilerplate code that is necessary to interact with contracts. One of the core goals of Aguesco is to abstract away this functionality and make it as easy as possible for developers to develop apps.

Augesco uses mobx-state-tree as it's state management system as an alternative to redux, the reasoning is best outlined here. With it, Augesco injects two stores, web3store which controls blockchain interactivity and contractstore which handles contract logic. The project also comes with out-of-the-box dapp components like metamask lockscreens and transaction notifiers. Included in this project is a sample contract which shows how the project works.

Requirements

  • MetaMask plugin

  • An infura api-key, which can be requested here

  • An ethereum account with testnet ether (rinkeby)

  • This project is best fitted for public blockchains but ganache can still be used. Use the latest beta as it has a websocket implementation. Please note that some event functionality does not work with ganache as well as it does for the public chain.

    npm install -g [email protected]

Alternatively, a local node + metamask can be used.

Setup

  • Clone this project

    git clone https://github.com/sirromdev/augesco.git

  • Install dependencies

    cd augesco && npm install

  • Once all dependencies are installed, truffle should be used to build and migrate the contracts to the blockchain. I found that the rinkeby test network works best. Once you have test ether, edit the account-config.js file and include your account mnemonic and infura key.

  • Compile your contract(s)

    truffle compile --all

  • Migrate the smart contracts to the blockchain. There should be a build folder present which holds the deployment in

    truffle migrate --network rinkeby

  • Start the local server and the page should auto render on localhost:3000

    npm start

How it works

The project is built around mobx-state-tree which is a state-management system similar to redux which has been traditionally used in blockchain dapps. Mobx-state-tree enables developers to model their data in a more object-orientated style.

Aguesco abstracts away blockchain interactivity by wrapping the folder in 3 layers called gates. They are found in our components folder:

  • web3gate interacts with the web3store model and determines user and network status. Should the user, change account, change network, lock their metamask or lose connection. The dapp automatically can detect this and renders the correct ux in this case.

  • contractgate is utilised to parse the contract logic. In our App.js file, we pass our contract json data from the build folder as an array contracts into props. When web3gate has loaded without issue, the contracts are automatically parsed and are contained within a map object in the contract store.

  • eventgate is not totally required by the project but is quite useful. The eventgate component detects all transactions executed by the user and displays the returned status. Also present is a drawer object which can subscribe to all new blockchain events from the application loads. Currently the optimal way to do this without utilising the blockchain load is to use the websocket endpoints provided by infura. These are declared in App.js similarly to how contracts are declared.


When accessing the two stores when building a dapp, I would advise using es6 syntax as below to save writing this.props everywhere.

const { web3Store, contractStore } = this.props  

In order to be able reference any model stores with mobx, we must inject the stores into our react components like so:

import { inject, observer } from "mobx-react"

@inject("web3Store")
@inject("contractStore")
@observer class AppContent extends Component {

ContractStore

contractStore.call(<contractName>, <function>, <args>)

  • <contractName> - string, name of the contract from which you wish to call
  • <function> - string, name of function within contract
  • <args> - array, arguments required, leave empty array if none needed

Using call(), we take an asynchronous read of the contract state which returns a promise. Below is a snippet of Counter.sol and its getter function getCount and an example of its execution.

function getCount() public view returns (uint){
  return count;
}

Using our contractStore we can do something like this:

let count = await contractStore.call("Counter", "getCount", [])

contractStore.exec(<contractName>, <function>, <args>, <options>)

  • <contractName> - string, name of the contract from which you wish to call
  • <function> - string, name of function within contract
  • <args> - array, arguments required, leave empty array if none needed
  • <options> - object, manipulates transaction details. See web3 docs for more.

exec() is to be used for any contract function that alters the state of the contract by a transaction. These functions are called setters. When used in this application, a popup will appear from metamask to confirm or reject the transaction. When setters are executed it usually takes 10-15 seconds until they are mined and resolved which lends itself to bad Ux. However, augesco provides a meaningful solution to this through transaction and event notifiers. Example:

function incCount() public {
  require(count < (2**256 - 1));
  count = count + 1;
  emit Increment(count, msg.sender);
}

This is then executed

contractStore.exec("Counter", "incCount", [], {
  "from": web3Store.account
})

contractStore.listen(<contractName>, <event>, <options>, <callback>)

  • <contractName> - string, name of the contract from which you wish to call
  • <event> - string, name of event within contract
  • <options> - object, filtering options. See web3 docs
  • <callback> - function, returns two arguments, err and event, event returns the event log data.

Solidity contracts have implemented events which can be used to track the state of a contract over time. Augesco has a listen() function which can be used to wait on changes to such functions. Looking at the incCount() function in the previous section, an Increment() event is emitted. By listening for emitted events, we can update our frontend representation in accordance with the changes through the callback. Example:

event Increment(
  uint count,
  address indexed sender
);
contractStore.listen("Counter", "Increment", {}, (err, event) => {...})

Using this, in tandem with an exec() function which emits a corresponding event can lead to a more reactive design.

contractStore.txEmitter.on(<eventName>, <data>)

For handling transaction logic, Aguesco implements a listener object which emits the status of a sent transaction. When we a new transaction is executed, from our exec() function, Aguesco keeps track of the transaction until it succeeds or fails. This involves a number of stages which is represented in constants.js The eventgate component uses the emitter extensively to provide popup notifications for the ui.

contractStore.txEmitter.on(txStatus.NEW, (hash) => {

  contractStore.txEmitter.once(txStatus.PENDING + hash, (data) => {})
  contractStore.txEmitter.on(txStatus.MINED + hash, (data) => {})
  contractStore.txEmitter.on(txStatus.SUCCESS + hash, (data) => {})
  contractStore.txEmitter.on(txStatus.FAILED + hash, (data) => {})

}

By nesting the on-events to be inside the new transaction, we can concatenate the status with its unique hash to provide more fine control for each event. This makes it easier when dealing with notifications.

Web3Store

web3Store.account - returns the current users account and should correspond directly with metamask

web3Store.balanceEth - returns the current users balance in standard ether

web3Store.balanceGwei - returns the current users balance in 1x10^9 eth (gwei)

web3Store.balanceWei - returns the current users balance in 1x10^18 eth (wei). Wei is the smallest denomination of ether possible.

web3Store.netName - returns the current network name

web3Store.chainEmitter

The chainEmitter object works similarly to the txEmitter and is used to monitor blockchain subscriptions. As of now, subscriptions to the pending transactions and new block headers are available to be used. The utility of being able to observe live data from the blockchain may improve user experience and possibly enable less-trusting users learn as to how the blockchain works.

Pending transactions are started and stopped:

  • web3Store.startPendingTxs()
  • web3Store.stopPendingTxs()

Once started, event result objects are emitted by the chainEmitter and can be caught anywhere within the application. We use the shorthand "ptx" as the eventname

web3Store.chainEmitter.on("ptx", data => {
  // do something with incoming transaction data
})

Similarly, new blocks are started and stopped

  • web3Store.startNewBlocks()
  • web3Store.stopNewBlocks()

We use "nbh" as the eventname

web3Store.chainEmitter.on("nbh", data => {
  // do something with incoming block headers
})

When both subscriptions are stopped, a single unsubscribe event is fired with the eventname + "-stopped" appended.

Design

The application uses antd as a css framework. Edits and overrides can be made using less in the assets folder. Ant makes it quite easy to generate a good looking ui but it can be easily removed using npm if material/semantic-ui etc are preferable.


AGUESCO - BEGIN TO DEVELOP

augesco's People

Contributors

padraic-o-mhuiris avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

augesco's Issues

Alter metamask injection and subscriptions method

Metamask will no longer be injecting web3

Also metamask is making changes to establishing event connectivity which is not currently operational in the injected web3 version. The reason being that it establishes a http connection and web3 1.0 is intending to be used with websockets.

Refactor contract and web3 models to single root model

  • Should provide better clarity from single source
  • Cumbersome having multiple web3 and web3.contract instances declared. Reducing to one will be an improvment
  • Interactivity between web3 contracts and general web3 functionality is also cumbersome and if integrated together, may provide easier development into the future

Create IPFS example component

  • Currently previewing an image before upload
  • On download, content is presented in an image tag

Get the file mime and and dependent on its format construct a ui to present that data.

Create fixed navbar outside router

The idea for this is issue is that the app contains a fixed navbar/titlebar which is does not changed based on the underlying content.

Antd, has a basic layout structure which has 4 main components, Header, Footer, Content and Sider. Using the routes config in App.js, the main key notifies, the component which we wish to render for a specific route. In the case for certain routes like our docs, the config should denote a sider key if it is intended and not in the case it doesn't.

fetchAccounts() is complex

fetchAccounts is called for every web3 update event. Both the instantiation method and the fetch could be changed.

Could be worth looking into refactoring much of the web3gate logic into the models. Not entirely sure if possible though

License

What license is associated with this repo? I am unable to locate it and am unable to use this without a license. If there is not one associated, would you mind adding a permissive license, such as an MIT license?

Implement IPFS linkup via infura or local server

  • Some issues surround infura ipfs caching and data permanency but should be a viable option for end user
  • Implementing a local ipfs server setup may be useful also.
  • Auto-integration of ipfs may need some research but ought not to be too overwhelming

Introduce routing for different components

  • Pre-rendering the event-log for the smart contract may be of some use
  • Would be necessary to organise functionality to seperate page
  • Component would be contained as wrapper and loaded from prop boolean
  • Dependent to event log understanding, the contract history could be demonstrated in a flow chart or simple table data

Logo design

Current icon is just a filler ethereum logo. Polygon is a nice design.

Generate contract reporting component

This is an extensive component and could be a project unto itself. The intention is to provide real-time reporting for the contracts specific to the dapp using the augesco project. It is more an example of the utility of the project rather than a feature but people may wish to use as such.

Branching idea from #3

Re-design augesco auth components

Alter the rendering of web3 and contract authentication and validation components. Use the antd layout system as opposed to row col and custom less attributes

Build out CI/CD platform

  • will require seperate branch staging
  • will require hosted server to integrate webhook deployment

Refactor account configuration for better user experience

  • outstanding minor issue for doing truffle migrations.
  • personal user mnemonic and infura key are instantiated in account-config
  • obviously not the most secure practice to declare mnemonic in file
  • rethink deployment method with truffle and research truffle-account integration

Display main page as docs

Reconstruct the main page where content in an api type style. As in, for each topic of information about aguesco, say, explaining aguesco.get(), give:

  • an example
  • explanation
  • code snippet

Infura/antd docs are good examples of this. The layout may need a completely new sidebar which also goes in tandem for #3 where more contract-blockchain specific information like the chainlog info should be

Generate project development model

  • CI/CD framework
  • git branching strategy
  • commit/feature planning
  • usage of kanban
  • investigation into how more collaborated projects are being built

End result may produce documentation pertaining to project development protocol

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.