Skip to content

Commit

Permalink
feat(contract): contract update
Browse files Browse the repository at this point in the history
  • Loading branch information
DophinL committed Dec 11, 2018
1 parent 3160dad commit 27e6ffc
Show file tree
Hide file tree
Showing 11 changed files with 290 additions and 21 deletions.
1 change: 1 addition & 0 deletions .babelrc
Expand Up @@ -41,6 +41,7 @@
"stage-0"
],
"plugins": [
"jsx-v-model",
"transform-vue-jsx"
]
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -138,6 +138,7 @@
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.5",
"babel-plugin-istanbul": "^4.1.1",
"babel-plugin-jsx-v-model": "^2.0.3",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
Expand Down
11 changes: 5 additions & 6 deletions src/renderer/components/LandingPage.vue
Expand Up @@ -66,7 +66,7 @@
import InfoPanel from './LandingPage/InfoPanel'
import AdmZip from 'adm-zip'
import PasswordConfirmModal from '@/components/common/PasswordConfirmModal'
import {mapState, mapGetters, mapActions} from 'vuex'
import {mapState, mapGetters, mapActions, mapMutations} from 'vuex'
import {ChainValidation} from 'gxbjs/es/index'
import {
deploy_contract
Expand All @@ -85,8 +85,6 @@
confirmDeployModalVisible: false,
contractName: '',
entry: '',
bytecode: '',
abi: {},
isCompiling: false,
tempPwd: '',
tempAsset: {},
Expand All @@ -95,7 +93,7 @@
},
computed: {
...mapGetters('ContractFiles', ['projects']),
...mapState(['wallets', 'currentWallet', 'assets']),
...mapState(['wallets', 'currentWallet', 'assets', 'abi', 'bytecode']),
fee() {
if (!this.deployTransaction) {
return 0
Expand Down Expand Up @@ -128,6 +126,7 @@
},
methods: {
...mapActions('ContractOperation', ['appendContract']),
...mapMutations(['SET_ABI', 'SET_BYTECODE']),
archiveFiles(entry) {
function recur(zip, files, base = '') {
files.forEach(function (file) {
Expand Down Expand Up @@ -214,10 +213,10 @@
this.$eventBus.$emit('log:push', log)
},
renderBytecode(bytecode) {
this.bytecode = bytecode
this.SET_BYTECODE(bytecode)
},
renderAbi(abi) {
this.abi = abi ? JSON.parse(abi) : {}
this.SET_ABI(abi ? JSON.parse(abi) : {})
},
onDeploy() {
let errMsg
Expand Down
141 changes: 134 additions & 7 deletions src/renderer/components/LandingPage/ContractList.vue
Expand Up @@ -11,6 +11,8 @@
style="display:inline-block;width:200px;vertical-align: middle;position: relative;top: -1px;">
{{contract.contractName}}
</div>
<Icon class="updateContract" type="md-refresh"
@click="onContractUpdateClick($event,contract)"></Icon>
<Icon class="closeContract" type="md-close" @click="onContractRemoveClick($event,contract)"></Icon>
<div slot="content">
<function-card v-for="f in contract.functions" :payable="f.payable" :abi="contract.abi"
Expand All @@ -26,11 +28,12 @@

<script>
import FunctionCard from './FunctionCard'
import {mapGetters, mapActions} from 'vuex'
import {mapGetters, mapActions, mapState} from 'vuex'
import {cloneDeep} from 'lodash'
import {fetch_account} from '@/services/WalletService'
import {fetch_account, update_contract} from '@/services/WalletService'
import {Form, FormItem, Input} from 'iview'
import {ChainValidation} from 'gxbjs/es/index'
import {confirmTransaction, confirmPassword} from '@/util/modalUtil'
function contractsFilter(contracts) {
return contracts.map(contract => {
Expand Down Expand Up @@ -60,13 +63,15 @@
Input
},
computed: {
...mapState(['abi', 'bytecode', 'currentWallet', 'curChainId']),
...mapGetters('ContractOperation', ['contractsFromCurChain']),
contracts() {
return contractsFilter(cloneDeep(this.contractsFromCurChain))
}
},
methods: {
...mapActions('ContractOperation', ['removeContract', 'appendContract']),
...mapActions('ContractOperation', {'updateContractAction': 'updateContract'}),
onContractRemoveClick(evt, contract) {
evt.stopPropagation()
this.$Modal.confirm({
Expand Down Expand Up @@ -132,18 +137,14 @@
name: ''
}
function handleInput(val) {
model.name = val
}
this.$Modal.confirm({
title: this.$t('contract.title.importContract'),
loading: true,
render: (h) => {
return (
<Form ref="form" style={{'margin-top': '30px'}} rules={rules} model={model}>
<FormItem prop="name">
<Input on-input={handleInput} value={model.name} autofocus={true}
<Input v-model={model.name} autofocus={true}
placeholder={this.$t('contract.placeholder.name.required')}/>
</FormItem>
</Form>
Expand All @@ -160,6 +161,126 @@
})
}
})
},
showUpdateContractModal(callback) {
var model = {
newOwner: ''
}
// TODO add rules
this.$Modal.confirm({
title: this.$t('contract.title.updateContract'),
loading: true,
render: (h) => {
return (
<Form ref="form" style={{'margin-top': '30px'}} model={model}>
<FormItem prop="newOwner">
<Input v-model={model.newOwner} autofocus={true}
placeholder={this.$t('suit your self')}/>
</FormItem>
</Form>
)
},
onOk: function () {
callback(model.newOwner)
}
})
},
onContractUpdateClick(evt, contract) {
this.showUpdateContractModal(newOwner => {
confirmPassword(async ({pwd, asset_id, asset}) => {
let items
try {
items = await this.buildUpdateItems(contract, newOwner, asset_id, asset, pwd)
} catch (err) {
return console.error(err)
}
confirmTransaction({
title: this.$t('contract.title.updateContractConfirm'),
items: items,
onOk: () => {
this.updateContract(asset_id, pwd, contract, newOwner).then((trx) => {
this.updateContractAction({
chainId: this.curChainId,
id: contract.id,
abi: this.abi
})
this.$logUtil.logClick('updateContractSuc')
const txid = trx[0].id
this.$eventBus.$emit('log:push', {
info: this.$t('contract.messages.updateContractSuc') + `,txid:${txid}`,
level: 'success'
})
this.$Message.success(this.$t('contract.messages.updateContractSuc'))
this.$store.dispatch('updateCurrentBalancesAndAssets')
}).catch(err => {
this.$logUtil.logClick('updateContractFail')
this.$eventBus.$emit('log:push', {
info: err,
level: 'error'
})
this.$Message.error(this.$t('contract.messages.updateContractFail'))
})
}
})
})
})
},
async buildUpdateItems(contract, newOwner, asset_id, asset, pwd) {
const items = [{
label: this.$t('contract.label.costAmount'),
desc: await this.getUpdateFeeStr(asset_id, asset, contract, newOwner, pwd)
}, {
label: this.$t('label.from'),
desc: this.currentWallet.account
}, {
label: this.$t('contract.label.name'),
desc: contract.contractName
}]
if (!!newOwner) {
items.push({
label: this.$t('contract.label.newOwner'),
desc: newOwner
})
}
return items
},
getUpdateFeeStr(asset_id, asset, contract, newOwner, pwd) {
return new Promise((resolve, reject) => {
this.updateContract(asset_id, pwd, contract, newOwner, false).then((trx) => {
const str = asset.symbol + ', ' + trx.serialize().operations[0][1].fee.amount / (10 ** asset.precision)
resolve(str)
}).catch(err => {
this.$eventBus.$emit('log:push', {
info: err,
level: 'error'
})
this.$Message.error(this.$t('contract.error.feeCompute'))
reject(err)
})
})
},
updateContract(asset_id, pwd, contract, newOwner, broadcast = true) {
return new Promise(async (resolve, reject) => {
const params = {
from: this.currentWallet.account,
contractName: contract.contractName,
code: this.bytecode,
abi: this.abi,
fee_id: asset_id,
password: pwd,
broadcast
}
if (!!newOwner) {
params.newOwner = newOwner
}
resolve(update_contract(params))
})
}
}
}
Expand All @@ -180,6 +301,12 @@
top: 14px;
}
.updateContract {
position: absolute;
right: 20px;
top: 14px;
}
.ivu-icon-md-add-circle {
position: relative;
top: 1px;
Expand Down
15 changes: 15 additions & 0 deletions src/renderer/const/persistState.js
@@ -0,0 +1,15 @@
export default [
'ContractFiles',
'ContractOperation',
'CppCompletion',
'apiServers',
'assets',
'balances',
'compileServers',
'curChainId',
'currentApiServer',
'currentApiServerStatus',
'currentCompileServer',
'currentWallet',
'wallets'
]
59 changes: 57 additions & 2 deletions src/renderer/services/WalletService.js
Expand Up @@ -117,7 +117,7 @@ const deploy_contract = ({from = '', contractName = '', code = '', abi = '', fee
let vm_version = '0'

return new Promise((resolve, reject) => {
resolve(Promise.all([fetch_account(from), unlock_wallet(from, password)]).then(results => {
resolve(Promise.all([fetch_account(from)]).then(results => {
let fromAcc = results[0]
if (!fromAcc) {
throw new Error(i18n.t('contract.error.fromAccountNotExist'))
Expand Down Expand Up @@ -163,7 +163,7 @@ const deploy_contract = ({from = '', contractName = '', code = '', abi = '', fee

const call_contract = (from, target, act, fee_id, password, broadcast = true, amount = {}) => {
return new Promise((resolve, reject) => {
resolve(Promise.all([fetch_account(from), fetch_account(target), unlock_wallet(from, password)]).then(results => {
resolve(Promise.all([fetch_account(from), fetch_account(target)]).then(results => {
let fromAcc = results[0]
let contractAccount = results[1]
if (!fromAcc) {
Expand Down Expand Up @@ -197,6 +197,60 @@ const call_contract = (from, target, act, fee_id, password, broadcast = true, am
})
}

/**
* update contract
* @param from
* @param contractName
* @param newOwner
* @param code
* @param abi
* @param password
* @param broadcast
*/
const update_contract = function ({from, contractName, newOwner, code, abi, fee_id, password, broadcast = true}) {
return new Promise((resolve, reject) => {
const promises = [fetch_account(from), fetch_account(contractName)]
if (!!newOwner) {
promises.push(fetch_account(newOwner))
}
resolve(Promise.all(promises).then(results => {
let fromAcc = results[0]
let contractAccount = results[1]

if (!fromAcc) {
throw new Error(i18n.t('contract.error.fromAccountNotExist'))
}

if (!contractAccount) {
throw new Error(i18n.t('contract.error.contractAccountNotExist'))
}

if (!!newOwner && !results[2]) {
throw new Error(i18n.t('contract.error.newOwnerAccountNotExist'))
}

let tr = new TransactionBuilder()
let opt = {
'fee': {
'amount': 0,
'asset_id': fee_id
},
owner: fromAcc.id,
contract: contractAccount.id,
code,
abi
}

if (newOwner) {
opt.new_owner = results[2].id
}

tr.add_operation(tr.get_type_operation('update_contract', opt))
return process_transaction(tr, from, password, broadcast)
}))
})
}

/**
* process transaction
* @param tr
Expand Down Expand Up @@ -317,6 +371,7 @@ export {
get_assets_by_ids,
fetch_account_balances,
call_contract,
update_contract,
fetch_account,
unlock_wallet,
process_transaction,
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/store/index.js
Expand Up @@ -8,6 +8,7 @@ import modules from './modules'
import createPersistedState from 'vuex-persistedstate/index'
import ElectronStore from 'electron-store'
import isElectron from 'is-electron'
import paths from '@/const/persistState'

Vue.use(Vuex)

Expand All @@ -17,6 +18,7 @@ let presistPlugin

if (isElectron()) {
presistPlugin = createPersistedState({
paths,
key: STORAGE_KEY,
storage: {
getItem: key => electronStore.get(key),
Expand All @@ -28,6 +30,7 @@ if (isElectron()) {
})
} else {
presistPlugin = createPersistedState({
paths,
key: STORAGE_KEY
})
}
Expand Down

0 comments on commit 27e6ffc

Please sign in to comment.