Required code for 3rd part, and described how to show/hide mint form

This commit is contained in:
Richard Ramos 2018-07-11 09:43:42 -04:00
parent 083304d001
commit 72d00b5ceb
2 changed files with 207 additions and 0 deletions

View File

@ -17,6 +17,7 @@ Let's edit the file `app/js/components/addToken.js` which contains the form to a
#### Importing Embark and contracts
Before being able to interact with the EVM, and with IPFS, you need to import both EmbarkJS and the contract file:
```
import web3 from "Embark/web3"
import EmbarkJS from 'Embark/EmbarkJS';
import SpaceshipToken from 'Embark/contracts/SpaceshipToken';
```

View File

@ -0,0 +1,206 @@
## Listing the newly minted tokens
As you can see when you browser the DApp at this point, we show a placeholder spaceship, just so we can see how a token would look like when all the functionality of the DApp is implemented.
Let's start by removing it. Open the file `app/js/index.js` and remove the constant `myShip` from `_loadMyShips()`. You also need to remove it from the `list` array.
Since we're going to use the SpaceshipToken contract, EmbarkJS and web3 functions, let's import them
```
import EmbarkJS from 'Embark/EmbarkJS';
import web3 from "Embark/web3"
import SpaceshipToken from 'Embark/contracts/SpaceshipToken';
```
_loadShipsForSale = async () => {
const { shipsForSaleN, shipsForSale, spaceshipPrices, spaceships } = SpaceshipToken.methods;
const total = await shipsForSaleN().call();
const list = [];
if(total){
for (let i = total-1; i >= 0; i--) {
const shipId = await shipsForSale(i).call();
const _info = await spaceships(shipId).call();
const _price = await spaceshipPrices(shipId).call();
const ship = {
price: _price,
id: shipId,
..._info
};
list.push(ship);
}
}
this.setState({shipsForSale: list.reverse()});
}
ships.js
import EmbarkJS from 'Embark/EmbarkJS';
import web3 from "Embark/web3"
import SpaceshipToken from 'Embark/contracts/SpaceshipToken';
componentDidMount(){
EmbarkJS.onReady((err) => {
this._loadAttributes();
});
}
_loadAttributes(){
// Cargar los atributos involucra leer la metadata
EmbarkJS.Storage.get(web3.utils.toAscii(this.props.metadataHash))
.then(content => {
const jsonMetadata = JSON.parse(content);
// Podemos usar este metodo
const _url = EmbarkJS.Storage.getUrl(jsonMetadata.imageHash);
// o leer el url que grabamos en la metadata
// const _url = jsonMetadata.image
this.setState({image: _url})
});
}
render(){
const { energy, lasers, shield, price, wallet, salesEnabled, marketplace } = this.props;
const { image, isSubmitting, showSellForm } = this.state;
const formattedPrice = !wallet ? web3.utils.fromWei(price, "ether") : '';
## Buying the tokens
buyFromStore = () => {
const { buySpaceship } = SpaceshipToken.methods;
const toSend = buySpaceship(this.props.id)
this.setState({isSubmitting: true});
toSend.estimateGas({value: this.props.price })
.then(estimatedGas => {
return toSend.send({from: web3.eth.defaultAccount,
value: this.props.price,
gas: estimatedGas + 1000000});
})
.then(receipt => {
console.log(receipt);
console.log("Updating ships");
this.props.onAction();
// TODO: show success
return true;
})
.catch((err) => {
console.error(err);
// TODO: show error blockchain
})
.finally(() => {
this.setState({isSubmitting: false});
});
}
## Listing our tokens
index.js
_loadMyShips = async () => {
const { balanceOf, tokenOfOwnerByIndex, spaceships } = SpaceshipToken.methods;
const total = await balanceOf(web3.eth.defaultAccount).call();
const list = [];
if(total){
for (let i = total-1; i >= 0; i--) {
const myShipId = await tokenOfOwnerByIndex(web3.eth.defaultAccount, i).call();
const _info = await spaceships(myShipId).call();
const ship = {
id: myShipId,
..._info
};
list.push(ship);
}
}
this.setState({myShips: list.reverse()});
}
## Showing and withdrawing the balance from sales
withdrawBalance.js
componentDidMount(){
EmbarkJS.onReady((err) => {
// Al cargar el componente, obtenemos el balance
this._getBalance();
});
}
_getBalance(){
// Se consulta el balance del contrato
web3.eth.getBalance(SpaceshipToken.options.address)
.then(newBalance => {
this.setState({
balance: web3.utils.fromWei(newBalance, "ether")
});
});
}
handleClick(e){
const { withdrawBalance } = SpaceshipToken.methods;
e.preventDefault();
this.setState({isSubmitting: true});
// Retiramos el balance total del contrato
// Estimamos primero el gas para saber cuanto gas enviar
const toSend = withdrawBalance();
toSend.estimateGas()
.then(estimatedGas => {
// Es una buena practica mandar siempre algo mas del gas estimado
return toSend.send({from: web3.eth.defaultAccount,
gas: estimatedGas + 1000});
})
.then(receipt => {
console.log(receipt);
this._getBalance();
// TODO mostrar info
return true;
})
.catch((err) => {
console.error(err);
// TODO: mostrar error
})
.finally(() => {
this.setState({isSubmitting: false});
});
}
## Display the mint form only if we are the owners of the contract
One thing you may have noticed is that the minting form shows up always even if you're not the owner of the contract. Our `SpaceshipToken` contract inherits from `Owned` which adds an `owner()` method that we can use to determine if the account browsing the dapp is the owner of the contract
For this, let's go back to `app/js/index.js`. The method `_isOwner` is called when the component mounts, due to it being a good place to load data from a remote endpoint (in this case, the EVM).
```
_isOwner(){
SpaceshipToken.methods.owner()
.call()
.then(owner => {
this.setState({isOwner: owner == web3.eth.defaultAccount});
return true;
});
}
```
> `web3.eth.defaultAccount` is always used by default in the `from` property when sending/calling a contract function. If you use the Status app, or Metamask, it will contain the account you use to create transactions.