mirror of
https://github.com/embarklabs/embark.git
synced 2025-02-18 16:46:38 +00:00
feat(scaffold): use ipfs in scaffold and upload file
This commit is contained in:
parent
168d774551
commit
9854368c24
@ -1,5 +1,6 @@
|
|||||||
import Handlebars from "handlebars";
|
import Handlebars from "handlebars";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
import { ABIDefinition } from "web3/types";
|
||||||
|
|
||||||
import { Contract } from "../../../../../typings/contract";
|
import { Contract } from "../../../../../typings/contract";
|
||||||
import { Embark } from "../../../../../typings/embark";
|
import { Embark } from "../../../../../typings/embark";
|
||||||
@ -11,6 +12,12 @@ const fs = require("../../../../core/fs");
|
|||||||
const utils = require("../../../../utils/utils");
|
const utils = require("../../../../utils/utils");
|
||||||
require("../../handlebarHelpers");
|
require("../../handlebarHelpers");
|
||||||
|
|
||||||
|
interface ABIDefinitionDecorated extends ABIDefinition {
|
||||||
|
isIpfsText?: boolean;
|
||||||
|
isIpfsFile?: boolean;
|
||||||
|
isStandard?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
const indexTemplatePath = path.join(__dirname, "templates", "index.html.hbs");
|
const indexTemplatePath = path.join(__dirname, "templates", "index.html.hbs");
|
||||||
const dappTemplatePath = path.join(__dirname, "templates", "dapp.js.hbs");
|
const dappTemplatePath = path.join(__dirname, "templates", "dapp.js.hbs");
|
||||||
|
|
||||||
@ -64,12 +71,48 @@ export class ReactBuilder implements Builder {
|
|||||||
|
|
||||||
const dappData = {
|
const dappData = {
|
||||||
contractName,
|
contractName,
|
||||||
functions: contract.abiDefinition.filter((entry) => entry.type === "function"),
|
functions: this.getFunctions(contract),
|
||||||
};
|
};
|
||||||
|
|
||||||
return [indexTemplate(indexData), dappTemplate(dappData)];
|
return [indexTemplate(indexData), dappTemplate(dappData)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getFunctions(contract: Contract) {
|
||||||
|
const ipfsAttributes = this.description.ipfsAttributes(contract.className);
|
||||||
|
|
||||||
|
return contract.abiDefinition.filter((entry) => entry.type === "function").map((entry) => {
|
||||||
|
const decorated: ABIDefinitionDecorated = entry;
|
||||||
|
const inputName = entry.inputs && entry.inputs.length > 1 ? entry.inputs[1].name.substring(1, entry.inputs[1].name.length) : "";
|
||||||
|
const functionName = entry.name || "";
|
||||||
|
|
||||||
|
Object.keys(ipfsAttributes).forEach((name) => {
|
||||||
|
let text = false;
|
||||||
|
if (ipfsAttributes[name] === "ipfsText") {
|
||||||
|
text = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ipfs = false;
|
||||||
|
if (name === inputName || `get${name.charAt(0).toUpperCase() + name.slice(1)}` === functionName) {
|
||||||
|
ipfs = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipfs) {
|
||||||
|
if (text) {
|
||||||
|
decorated.isIpfsText = true;
|
||||||
|
} else {
|
||||||
|
decorated.isIpfsFile = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!decorated.isIpfsText && !decorated.isIpfsFile) {
|
||||||
|
decorated.isStandard = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return decorated;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private installDependencies() {
|
private installDependencies() {
|
||||||
const cmd = "npm install react react-bootstrap react-dom";
|
const cmd = "npm install react react-bootstrap react-dom";
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
@ -32,13 +32,19 @@ class {{capitalize name}}Form{{@index}} extends Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange(e, name){
|
handleChangeFile(e) {
|
||||||
|
const {input} = this.state;
|
||||||
|
input.file = [e.target];
|
||||||
|
this.setState({input});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange(e, name) {
|
||||||
const {input} = this.state;
|
const {input} = this.state;
|
||||||
input[name] = e.target.value;
|
input[name] = e.target.value;
|
||||||
this.setState({input});
|
this.setState({input});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCheckbox(e, name){
|
handleCheckbox(e, name) {
|
||||||
const {input} = this.state;
|
const {input} = this.state;
|
||||||
input[name] = e.target.checked;
|
input[name] = e.target.checked;
|
||||||
this.setState({input});
|
this.setState({input});
|
||||||
@ -52,6 +58,7 @@ class {{capitalize name}}Form{{@index}} extends Component {
|
|||||||
this.setState({output: null, error: null, receipt: null});
|
this.setState({output: null, error: null, receipt: null});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
{{#if isStandard}}
|
||||||
{{#ifview stateMutability}}
|
{{#ifview stateMutability}}
|
||||||
const result = await {{../contractName}}.methods{{methodname ../functions name inputs}}({{#each inputs}}input.{{#ifeq name ''}}field{{else}}{{trim name}}{{/ifeq}}{{#unless @last}}, {{/unless}}{{/each}}).call();
|
const result = await {{../contractName}}.methods{{methodname ../functions name inputs}}({{#each inputs}}input.{{#ifeq name ''}}field{{else}}{{trim name}}{{/ifeq}}{{#unless @last}}, {{/unless}}{{/each}}).call();
|
||||||
{{#iflengthgt outputs 1}}
|
{{#iflengthgt outputs 1}}
|
||||||
@ -86,6 +93,51 @@ class {{capitalize name}}Form{{@index}} extends Component {
|
|||||||
|
|
||||||
this.setState({receipt});
|
this.setState({receipt});
|
||||||
{{/ifview}}
|
{{/ifview}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isIpfsText}}
|
||||||
|
{{#ifview stateMutability}}
|
||||||
|
const result = await {{../contractName}}.methods{{methodname ../functions name inputs}}({{#each inputs}}input.{{#ifeq name ''}}field{{else}}{{trim name}}{{/ifeq}}{{#unless @last}}, {{/unless}}{{/each}}).call();
|
||||||
|
const data = await EmbarkJS.Storage.get(result);
|
||||||
|
this.setState({output: data});
|
||||||
|
{{else}}
|
||||||
|
const hash = await EmbarkJS.Storage.saveText(input.{{inputs.1.name}});
|
||||||
|
const toSend = {{../contractName}}.methods{{methodname ../functions name inputs}}(input.{{inputs.0.name}}, hash);
|
||||||
|
|
||||||
|
const estimatedGas = await toSend.estimateGas({from: web3.eth.defaultAccount});
|
||||||
|
|
||||||
|
const receipt = await toSend.send({
|
||||||
|
from: web3.eth.defaultAccount,
|
||||||
|
gasLimit: estimatedGas
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(receipt);
|
||||||
|
|
||||||
|
this.setState({receipt});
|
||||||
|
{{/ifview}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isIpfsFile}}
|
||||||
|
{{#ifview stateMutability}}
|
||||||
|
const result = await {{../contractName}}.methods{{methodname ../functions name inputs}}({{#each inputs}}input.{{#ifeq name ''}}field{{else}}{{trim name}}{{/ifeq}}{{#unless @last}}, {{/unless}}{{/each}}).call();
|
||||||
|
const url = EmbarkJS.Storage.getUrl(result);
|
||||||
|
this.setState({output: url});
|
||||||
|
{{else}}
|
||||||
|
const hash = await EmbarkJS.Storage.uploadFile(input.file)
|
||||||
|
const toSend = {{../contractName}}.methods{{methodname ../functions name inputs}}(input._id, hash);
|
||||||
|
|
||||||
|
const estimatedGas = await toSend.estimateGas({from: web3.eth.defaultAccount});
|
||||||
|
|
||||||
|
const receipt = await toSend.send({
|
||||||
|
from: web3.eth.defaultAccount,
|
||||||
|
gasLimit: estimatedGas
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(receipt);
|
||||||
|
|
||||||
|
this.setState({receipt});
|
||||||
|
{{/ifview}}
|
||||||
|
{{/if}}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.setState({error: err.message});
|
this.setState({error: err.message});
|
||||||
@ -99,6 +151,34 @@ class {{capitalize name}}Form{{@index}} extends Component {
|
|||||||
<h3>{{name}}</h3>
|
<h3>{{name}}</h3>
|
||||||
<form>
|
<form>
|
||||||
{{#if inputs.length}}
|
{{#if inputs.length}}
|
||||||
|
{{#if isIpfsFile}}
|
||||||
|
{{#ifview stateMutability}}
|
||||||
|
<FormGroup>
|
||||||
|
<ControlLabel>_id</ControlLabel>
|
||||||
|
<FormControl
|
||||||
|
type="text"
|
||||||
|
placeholder="uint256"
|
||||||
|
onChange={(e) => this.handleChange(e, '_id')}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
{{else}}
|
||||||
|
<FormGroup>
|
||||||
|
<ControlLabel>_id</ControlLabel>
|
||||||
|
<FormControl
|
||||||
|
type="text"
|
||||||
|
placeholder="uint256"
|
||||||
|
onChange={(e) => this.handleChange(e, '_id')}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup>
|
||||||
|
<ControlLabel>File</ControlLabel>
|
||||||
|
<FormControl
|
||||||
|
type="file"
|
||||||
|
onChange={(e) => this.handleChangeFile(e)}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
{{/ifview}}
|
||||||
|
{{else}}
|
||||||
{{#each inputs}}
|
{{#each inputs}}
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<ControlLabel>{{#ifeq name ''}}field{{else}}{{name}}{{/ifeq}}</ControlLabel>
|
<ControlLabel>{{#ifeq name ''}}field{{else}}{{name}}{{/ifeq}}</ControlLabel>
|
||||||
@ -117,6 +197,7 @@ class {{capitalize name}}Form{{@index}} extends Component {
|
|||||||
</FormGroup>
|
</FormGroup>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
{{#if payable}}
|
{{#if payable}}
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<ControlLabel>Value</ControlLabel>
|
<ControlLabel>Value</ControlLabel>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user