Skip to content

Commit

Permalink
Merge pull request #14 from a1300/register_publisher_asset
Browse files Browse the repository at this point in the history
Register publisher, asset and issue tokens
  • Loading branch information
a1300 authored Jul 9, 2018
2 parents 4c15ddf + 8e180c4 commit c8bbf4e
Show file tree
Hide file tree
Showing 17 changed files with 759 additions and 16 deletions.
17 changes: 8 additions & 9 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,17 @@
}
},
{
"name": "Run mocha",
"name": "Run mocha",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/.bin/mocha",
"stopOnEntry": false,
"args": [ "test/index.js" ],
"cwd": "${workspaceFolder}/",
"runtimeExecutable": null,
"env": {
"program": "${workspaceFolder}/node_modules/.bin/mocha",
"stopOnEntry": false,
"args": [ "test/index.js" ],
"cwd": "${workspaceFolder}/",
"runtimeExecutable": null,
"env": {
"NODE_ENV": null
}
}

}
]
}
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,25 @@ $ asch-redeploy

# asch-redeploy Options

### --publisher name
`--publisher` Registers the `master` account (see below) as a publisher. With the publisher it is possible to register multiple assets. One account can only be registered as one publisher.

### --asset name
`--asset` Registers an asset.

> Example:
> Publisher: `CCTime`, Asset: `XCT`
> Creates asset `CCTime.XCT`, this asset can be used in Dapps.
<img src="./docs/blob/publisher_asset_option.png" alt="asch" style="width:550px;"/>

### --asch directory
`-a --asch` Points to the `asch` directory where the local Asch blockchain lives. Default `../asch`

<img src="./docs/blob/asch_option.png" alt="asch" style="width:550px;"/>

### --host name
`-h --host` Set the host name on which the local Asch node should be started. Default `localhost`
`-h --host` Set the host name on which the local Asch node should be started. Default `http://localhost`

### --port number
`-p --port` Set the port on which the local Asch node should be started. Default `4096`
Expand Down
2 changes: 2 additions & 0 deletions docs/Todo.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# TODO
* Add option for resetting the asch database
* Just delete the `blockchain.db` file
* Add option to fuel the dapp after deployment
* Possible Refactoring
* Merge the two methods in CreateLogDir into one
Expand Down
Binary file added docs/blob/publisher_asset_option.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "asch-redeploy",
"version": "1.0.2",
"version": "1.0.3",
"description": "A hassle-free local asch environment",
"main": "index.js",
"dependencies": {
Expand Down
18 changes: 17 additions & 1 deletion src/DI.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const Watcher = require('./orchestration/watcher')
const CheckPublicDistDir = require('./startup/checkPublicDistDir')
const RefuelDapp = require('./orchestration/refuelDapp')
const PathResolution = require('./pathResolution')
const UIA = require('./orchestration/uia/uia')
const RegisterPublisher = require('./orchestration/uia/registerPublisher')
const RegisterAsset = require('./orchestration/uia/registerAsset')
const CreateTokens = require('./orchestration/uia/createTokens')
const FILETYPES = {
SendMoney: 'SendMoney',
RegisterDapp: 'RegisterDapp',
Expand All @@ -32,7 +36,11 @@ const FILETYPES = {
Watcher: 'Watcher',
CheckPublicDistDir: 'CheckPublicDistDir',
RefuelDapp: 'RefuelDapp',
PathResolution: 'PathResolution'
PathResolution: 'PathResolution',
UIA: 'UIA',
RegisterPublisher: 'RegisterPublisher',
RegisterAsset: 'RegisterAsset',
CreateTokens: 'CreateTokens'
}

const userInput = require('./program').getUserInput()
Expand Down Expand Up @@ -97,6 +105,10 @@ helpers.annotate(Watcher, [DEPENDENCIES.Config, DEPENDENCIES.Logger, DEPENDENCIE
helpers.annotate(CheckPublicDistDir, [DEPENDENCIES.Config, DEPENDENCIES.Fs, DEPENDENCIES.Path])
helpers.annotate(RefuelDapp, [DEPENDENCIES.Config, DEPENDENCIES.Axios, DEPENDENCIES.AschJS, DEPENDENCIES.Logger])
helpers.annotate(PathResolution, [DEPENDENCIES.Config, DEPENDENCIES.Logger, DEPENDENCIES.Path])
helpers.annotate(UIA, [DEPENDENCIES.Config, DEPENDENCIES.Logger, FILETYPES.RegisterPublisher, FILETYPES.RegisterAsset, FILETYPES.CreateTokens])
helpers.annotate(RegisterPublisher, [DEPENDENCIES.Config, DEPENDENCIES.AschJS, DEPENDENCIES.Axios, DEPENDENCIES.Logger, DEPENDENCIES.Promise])
helpers.annotate(RegisterAsset, [DEPENDENCIES.Config, DEPENDENCIES.AschJS, DEPENDENCIES.Axios, DEPENDENCIES.Logger, DEPENDENCIES.Promise])
helpers.annotate(CreateTokens, [DEPENDENCIES.Config, DEPENDENCIES.AschJS, DEPENDENCIES.Axios, DEPENDENCIES.Logger, DEPENDENCIES.Promise])

let setup = function () {
// bindings
Expand All @@ -115,6 +127,10 @@ let setup = function () {
container.bind(FILETYPES.CheckPublicDistDir).to(CheckPublicDistDir)
container.bind(FILETYPES.RefuelDapp).to(RefuelDapp)
container.bind(FILETYPES.PathResolution).to(PathResolution)
container.bind(FILETYPES.UIA).to(UIA)
container.bind(FILETYPES.RegisterPublisher).to(RegisterPublisher)
container.bind(FILETYPES.RegisterAsset).to(RegisterAsset)
container.bind(FILETYPES.CreateTokens).to(CreateTokens)

// constants or third party libraries
const registerConstantValue = helpers.registerConstantValue(container)
Expand Down
13 changes: 9 additions & 4 deletions src/orchestration/refuelDapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ let RefuelDapp = function (config, axios, aschJS, logger) {
this.aschJS = aschJS
this.logger = logger

this.transferCurrency = 'XAS'

this.headers = {
magic: this.config.node.magic,
version: ''
Expand All @@ -16,11 +18,14 @@ let RefuelDapp = function (config, axios, aschJS, logger) {
reject(new Error('dappId must be of type string'))
}

let currency = 'XAS'
if (this.config.uia && this.config.uia.publisher && this.config.uia.asset) {
this.transferCurrency = `${this.config.uia.publisher}.${this.config.uia.asset}`
}

let amount = 500 * 1e8
let transaction = this.aschJS.transfer.createInTransfer(dappId, currency, amount, config.dapp.masterAccountPassword, config.dapp.masterAccountPassword2nd || undefined)
let transaction = this.aschJS.transfer.createInTransfer(dappId, this.transferCurrency, amount, config.dapp.masterAccountPassword, config.dapp.masterAccountPassword2nd || undefined)

let url = 'http://localhost:4096/peer/transactions'
let url = `${this.config.node.host}:${this.config.node.port}/peer/transactions`

this.axios.post(url, {
transaction: transaction
Expand All @@ -35,7 +40,7 @@ let RefuelDapp = function (config, axios, aschJS, logger) {
this.logger.warn(`dapp refuel was not successful ${JSON.stringify(response.data)}`)
throw new Error(response.data)
}
this.logger.info(`DAPP refuel with ${amount / 1e8} XAS, transactionId: "${response.data.transactionId}"`)
this.logger.info(`DAPP refuel with ${amount / 1e8} ${this.transferCurrency}, transactionId: "${response.data.transactionId}"`)
resolve(response.data.transactionId)
})
.catch((error) => {
Expand Down
99 changes: 99 additions & 0 deletions src/orchestration/uia/createTokens.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@

// ctor
let CreateTokens = function (config, aschJS, axios, logger, promise) {
this.config = config
this.aschJS = aschJS
this.axios = axios
this.logger = logger
this.promise = promise

this.getAssetBalance = () => {
let publicKey = this.aschJS.crypto.getKeys(this.config.dapp.masterAccountPassword).publicKey
let address = this.aschJS.crypto.getAddress(publicKey)
let currency = `${this.config.uia.publisher}.${this.config.uia.asset}`
let url = `${this.config.node.host}:${this.config.node.port}/api/uia/balances/${address}/${currency}`

return this.axios.get(url)
}

this.processAssetBalance = (response) => {
// 0 balance: {"success":false,"error":"Balance info not found"}
// hasBalance: {"success":true,"balance":{"currency":"CCTime.XCT","balance":"2000000000000","maximum":"1000000000000000000","precision":8,"quantity":"2000000000000","writeoff":0,"allowWriteoff":0,"allowWhitelist":0,"allowBlacklist":0,"maximumShow":"10000000000","quantityShow":"20000","balanceShow":"20000"}}

if (response.status === 200) {
if (response.data.success === false && response.data.error === 'Balance info not found') {
return true
}

let threshold = 10000
if (response.data.balance && response.data.balance.balanceShow > threshold) {
this.logger.info(`Balance: ${response.data.balance.balanceShow} ${this.config.uia.asset}`, { meta: 'inverse' })
throw new Error('enough_tokens')
} else {
return true
}
} else {
throw new Error('error_during_requesting_asset_balance')
}
}

this.createTokens = () => {
let currency = `${this.config.uia.publisher}.${this.config.uia.asset}`
let amount = (20000 * 1e8).toString()

let transaction = aschJS.uia.createIssue(currency, amount, this.config.dapp.masterAccountPassword, this.config.dapp.masterAccountPassword2nd)

let url = `${this.config.node.host}:${this.config.node.port}/peer/transactions`
let data = {
transaction: transaction
}
let headers = {
headers: {
magic: this.config.node.magic,
version: ''
}
}

return axios.post(url, data, headers)
}

this.processCreateTokens = (response) => {
if (response.status === 200) {
if (response.data.success === true) {
let amount = 20000
this.logger.info(`${amount} ${this.config.uia.asset} tokens successfully created`, { meta: 'inverse' })
return true
} else {
throw new Error(`error_during_creation_of_tokens, ${response.data.error}`)
}
} else {
throw new Error('error_during_creation_of_tokens')
}
}

this.start = () => {
return this.getAssetBalance()
.then((response) => {
return this.processAssetBalance(response)
})
.then(() => {
return this.createTokens()
})
.then((response) => {
return this.processCreateTokens(response)
})
.then(() => {
this.logger.info(`waiting 11 sec for the create token transaction to be persisted to the next block...`)
return this.promise.delay(11000)
})
.catch((error) => {
if (error.message.startsWith('enough_tokens')) {
return true
} else {
throw error
}
})
}
}

module.exports = CreateTokens
120 changes: 120 additions & 0 deletions src/orchestration/uia/registerAsset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

// ctor
let RegisterAsset = function (config, aschJS, axios, logger, promise) {
this.config = config
this.aschJS = aschJS
this.axios = axios
this.logger = logger
this.promise = promise

this.waitingMS = 11000

this.existsAsset = () => {
let url = `${this.config.node.host}:${this.config.node.port}/api/uia/assets/${this.config.uia.publisher}.${this.config.uia.asset}`

return axios.get(url)
}

this.handleExistsAsset = (result) => {
/*
http://localhost:4096/api/uia/assets/CCtime.XCT
response assetExists: {
"success":true,
"asset": {
"name":"CCtime.XCT",
"desc":"xct",
"maximum":"10000000000000",
"precision":8,
"strategy":"",
"quantity":"0",
"height":20,
"issuerId":"AHMCKebuL2nRYDgszf9J2KjVZzAw95WUyB",
"acl":0,
"writeoff":0,
"allowWriteoff":0,
"allowWhitelist":0,
"allowBlacklist":0,
"maximumShow":"100000",
"quantityShow":"0"
}
}
response assetExistsNot: {
"success":false,
"error":"Asset not found"
}
*/

if (result.status === 200) {
if (result.data.success === true) {
throw new Error('already_registered')
} else {
return true
}
} else {
throw new Error('could_not_load_assets')
}
}

this.register = () => {
let name = `${config.uia.publisher}.${config.uia.asset}`
let desc = name
let maximum = '1000000000000000000'
let precision = 8
let strategy = ''
let allowWriteoff = 0
let allowWhitelist = 0
let allowBlacklist = 0

let transaction = aschJS.uia.createAsset(name, desc, maximum, precision, strategy, allowWriteoff, allowWhitelist, allowBlacklist, this.config.dapp.masterAccountPassword, this.config.dapp.masterAccountPassword2nd)

let url = `${this.config.node.host}:${this.config.node.port}/peer/transactions`
let data = {
transaction: transaction
}
let headers = {
headers: {
magic: this.config.node.magic,
version: ''
}
}

return axios.post(url, data, headers)
}

this.handleRegister = (response) => {
if (response.data.success === true) {
let asset = this.config.uia.asset
this.logger.info(`asset "${asset}" registered`, { meta: 'inverse' })
return true
}
}

this.start = () => {
return this.existsAsset()
.then((response) => {
return this.handleExistsAsset(response)
})
.then((response) => {
return this.register()
})
.then((response) => {
return this.handleRegister(response)
})
.then(() => {
this.logger.info(`waiting 11 sec for asset registration transaction to be written in block...`)
return this.promise.delay(this.waitingMS)
})
.then(() => {
return true
})
.catch((error) => {
if (error.message.startsWith('already_registered')) {
return true
} else {
throw error
}
})
}
}

module.exports = RegisterAsset
Loading

0 comments on commit c8bbf4e

Please sign in to comment.