diff --git a/src/structs.js b/src/structs.js index d0890f029..c37e2a318 100644 --- a/src/structs.js +++ b/src/structs.js @@ -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 @@ -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) }, @@ -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 } @@ -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') } } } @@ -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') } } } @@ -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) } })