TokenScript has a declarative part (data-object schema, attribute typing) and a runtime part (views and actions). We usually process the declarative part before running the executable part. However, it is sometimes required to perform on attribute inputs or outputs.
A simple example, say we need to use the token balance as an input to an attribute that is a contract call result; but before we use it - for some reason - we need to double the value. The attribute result is required to be in the rendered view.
Consider this attribute which is a function:
<ts:attribute-type id="valueWeNeed" syntax="1.3.6.1.4.1.1466.115.121.1.15">
<ts:origins>
<ethereum:call function="getValue" as="utf8" contract="MyCoin">
<ts:data>
<ts:uint256 ref="inputVal"></ts:bytes32>
</ts:data>
</ethereum:call>
</ts:origins>
</ts:attribute-type>
It's an attribute that needs to be displayed in the token view. However one of the inputs to the transaction that this function requires some pre-calculation work before submitting to the transaction.
val inputVal = this.props.balance * 2;
document.getElementById("iVal").value = inputVal;
Now this can be picked up by another attribute:
<ts:attribute-type id="inputVal" syntax="1.3.6.1.4.1.1466.115.121.1.36">
<ts:label>
<ts:string>iVal</ts:string> <!-- This is the element name in the JavaScript -->
</ts:label>
<ts:origins>
<ts:element-value as="uint256"></ts:element-value>
</ts:origins>
</ts:attribute-type>
the <element-value>
is an indication to the parser that this value is obtained from a DOM element value iVal
from the view. Therefore the parser knows it has to render the view before it can obtain iVal
and then use that in the inputValue
attribute for valueWeNeed
, like this:
document.getElementById("info").innerText = `Value you needed is ${this.props.valueWeNeed}`;