Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Default "symbol" and "asset" types to eosio.token contract #152
Browse files Browse the repository at this point in the history
  • Loading branch information
James Calfee committed May 31, 2018
1 parent 44ff378 commit 2260427
Showing 1 changed file with 69 additions and 96 deletions.
165 changes: 69 additions & 96 deletions src/structs.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,10 @@ const PublicKeyEcc = (validation) => {
}
}

/** Current action within a transaction. */
let currentAccount

/** @private */
function precisionCache(assetCache, value) {
const symbolInfo = parseExtendedAsset(value)
const contract = symbolInfo.contract || currentAccount
const contract = symbolInfo.contract || 'eosio.token'

let precision

Expand Down Expand Up @@ -259,7 +256,7 @@ const Symbol = assetCache => validation => {

appendByteBuffer (b, value) {
const {symbol, precision} = precisionCache(assetCache, value)
assert(precision != null, `Precision unknown for asset: ${symbol}@${currentAccount}`)
assert(precision != null, `Precision unknown for asset: ${symbol}@eosio.token`)
const pad = '\0'.repeat(7 - symbol.length)
b.append(String.fromCharCode(precision) + symbol + pad)
},
Expand Down Expand Up @@ -329,20 +326,27 @@ function toAssetString(value, assetCache, format = '') {

const {precision, symbol, amount, contract} = precisionCache(assetCache, value)

if(format === 'plain') {
if(format === 'plain_asset') {
return `${UDecimalPad(amount, precision)} ${symbol}`
}

if(format === 'extended') {
if(format === 'extended_asset') {
const contractSuffix = contract ? `@${contract}` : ''
return `${UDecimalPad(amount, precision)} ${symbol}${contractSuffix}`
}

if(format === 'full') {
if(format === 'full_asset') {
const precisionPrefix = precision != null ? `${precision},` : ''
const full = `${UDecimalPad(amount, precision)} ${precisionPrefix}${symbol}`
// console.log('full_asset', full)
return full
}

if(format === 'full_extended_asset') {
const contractSuffix = contract ? `@${contract}` : ''
const precisionPrefix = precision != null ? `${precision},` : ''
const full = `${UDecimalPad(amount, precision)} ${precisionPrefix}${symbol}${contractSuffix}`
// console.log('full', full)
// console.log('full_extended_asset', full)
return full
}

Expand All @@ -362,26 +366,26 @@ const Asset = assetCache => (validation, baseTypes, customTypes) => {
const amount = amountType.fromByteBuffer(b)
const sym = symbolType.fromByteBuffer(b)
const {precision, symbol} = precisionCache(assetCache, sym)
return toAssetString(`${UDecimalUnimply(amount, precision)} ${precision},${symbol}`, assetCache, 'full')
return toAssetString(`${UDecimalUnimply(amount, precision)} ${precision},${symbol}`, assetCache, 'full_asset')
},

appendByteBuffer (b, value) {
assert.equal(typeof value, 'string', `expecting asset string, got ` + (typeof value))
const {amount, precision, symbol, contract} = precisionCache(assetCache, value)
const {amount, precision, symbol} = precisionCache(assetCache, value)
assert(precision != null, `Precision unknown for asset: ${value}`)
amountType.appendByteBuffer(b, UDecimalImply(amount, precision))
symbolType.appendByteBuffer(b, value)
},

fromObject (value) {
return toAssetString(value, assetCache, 'full')
return toAssetString(value, assetCache, 'full_asset')
},

toObject (value) {
if (validation.defaults && value == null) {
return '0.0001 SYS'
}
return toAssetString(value, assetCache, 'plain')
return toAssetString(value, assetCache, 'plain_asset')
}
}
}
Expand Down Expand Up @@ -414,15 +418,14 @@ const ExtendedAsset = assetCache => (validation, baseTypes, customTypes) => {
// like: 1.0000 SYS@contract or 1 SYS@contract
assert(/^\d+(\.\d+)* [A-Z]+@[a-z0-5]+(\.[a-z0-5]+)*$/.test(value),
'Invalid extended asset: ' + value)

return toAssetString(value, assetCache, 'full')
return toAssetString(value, assetCache, 'full_extended_asset')
},

toObject (value) {
if (validation.defaults && value == null) {
return '1.0000 SYS@eosio.token'
}
return toAssetString(value, assetCache, 'extended')
return toAssetString(value, assetCache, 'extended_asset')
}
}
}
Expand Down Expand Up @@ -519,105 +522,75 @@ const wasmCodeOverride = config => ({
*/
const actionDataOverride = (structLookup, forceActionDataHex) => ({
'action.data.fromByteBuffer': ({fields, object, b, config}) => {
currentAccount = object.account
try {
const ser = (object.name || '') == '' ? fields.data : structLookup(object.name, object.account)
if(ser) {
b.readVarint32() // length prefix (usefull if object.name is unknown)
object.data = ser.fromByteBuffer(b, config)
} else {
// console.log(`Unknown Action.name ${object.name}`)
const lenPrefix = b.readVarint32()
const bCopy = b.copy(b.offset, b.offset + lenPrefix)
b.skip(lenPrefix)
object.data = Buffer.from(bCopy.toBinary(), 'binary')
}
} catch(error) {
throw error
} finally {
currentAccount = null
const ser = (object.name || '') == '' ? fields.data : structLookup(object.name, object.account)
if(ser) {
b.readVarint32() // length prefix (usefull if object.name is unknown)
object.data = ser.fromByteBuffer(b, config)
} else {
// console.log(`Unknown Action.name ${object.name}`)
const lenPrefix = b.readVarint32()
const bCopy = b.copy(b.offset, b.offset + lenPrefix)
b.skip(lenPrefix)
object.data = Buffer.from(bCopy.toBinary(), 'binary')
}
},

'action.data.appendByteBuffer': ({fields, object, b}) => {
currentAccount = object.account
try {
const ser = (object.name || '') == '' ? fields.data : structLookup(object.name, object.account)
if(ser) {
const b2 = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN)
ser.appendByteBuffer(b2, object.data)
b.writeVarint32(b2.offset)
b.append(b2.copy(0, b2.offset), 'binary')
} else {
// console.log(`Unknown Action.name ${object.name}`)
const data = typeof object.data === 'string' ? new Buffer(object.data, 'hex') : object.data
if(!Buffer.isBuffer(data)) {
throw new TypeError(`Unknown struct '${object.name}' for contract '${object.account}', locate this struct or provide serialized action.data`)
}
b.writeVarint32(data.length)
b.append(data.toString('binary'), 'binary')
const ser = (object.name || '') == '' ? fields.data : structLookup(object.name, object.account)
if(ser) {
const b2 = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN)
ser.appendByteBuffer(b2, object.data)
b.writeVarint32(b2.offset)
b.append(b2.copy(0, b2.offset), 'binary')
} else {
// console.log(`Unknown Action.name ${object.name}`)
const data = typeof object.data === 'string' ? new Buffer(object.data, 'hex') : object.data
if(!Buffer.isBuffer(data)) {
throw new TypeError(`Unknown struct '${object.name}' for contract '${object.account}', locate this struct or provide serialized action.data`)
}
} catch(error) {
throw error
} finally {
currentAccount = null
b.writeVarint32(data.length)
b.append(data.toString('binary'), 'binary')
}
},

'action.data.fromObject': ({fields, object, result}) => {
const {data, name} = object
currentAccount = object.account

try {
const ser = (name || '') == '' ? fields.data : structLookup(name, object.account)
if(ser) {
if(typeof data === 'object') {
result.data = ser.fromObject(data) // resolve shorthand
} else if(typeof data === 'string') {
const buf = new Buffer(data, 'hex')
result.data = Fcbuffer.fromBuffer(ser, buf)
} else {
throw new TypeError('Expecting hex string or object in action.data')
}
const ser = (name || '') == '' ? fields.data : structLookup(name, object.account)
if(ser) {
if(typeof data === 'object') {
result.data = ser.fromObject(data) // resolve shorthand
} else if(typeof data === 'string') {
const buf = new Buffer(data, 'hex')
result.data = Fcbuffer.fromBuffer(ser, buf)
} else {
// console.log(`Unknown Action.name ${object.name}`)
result.data = data
throw new TypeError('Expecting hex string or object in action.data')
}
} catch(error) {
throw error
} finally {
currentAccount = null
} else {
// console.log(`Unknown Action.name ${object.name}`)
result.data = data
}
},

'action.data.toObject': ({fields, object, result, config}) => {
const {data, name} = object || {}
currentAccount = object.account

try {
const ser = (name || '') == '' ? fields.data : structLookup(name, object.account)
if(!ser) {
// Types without an ABI will accept hex
result.data = Buffer.isBuffer(data) ? data.toString('hex') : data
return
}
const ser = (name || '') == '' ? fields.data : structLookup(name, object.account)
if(!ser) {
// Types without an ABI will accept hex
result.data = Buffer.isBuffer(data) ? data.toString('hex') : data
return
}

if(forceActionDataHex) {
const b2 = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN)
if(data) {
ser.appendByteBuffer(b2, data)
}
result.data = b2.copy(0, b2.offset).toString('hex')
// console.log('result.data', result.data)
return
if(forceActionDataHex) {
const b2 = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN)
if(data) {
ser.appendByteBuffer(b2, data)
}

// Serializable JSON
result.data = ser.toObject(data, config)
} catch(error) {
throw error
} finally {
currentAccount = null
result.data = b2.copy(0, b2.offset).toString('hex')
// console.log('result.data', result.data)
return
}

// Serializable JSON
result.data = ser.toObject(data, config)
}
})

0 comments on commit 2260427

Please sign in to comment.