Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduce learning curve by sticking to ABI construction #191

Open
SmartLayer opened this issue Jun 3, 2019 · 7 comments
Open

reduce learning curve by sticking to ABI construction #191

SmartLayer opened this issue Jun 3, 2019 · 7 comments

Comments

@SmartLayer
Copy link

SmartLayer commented Jun 3, 2019

Consider this:

        <ts:transaction>
            <ts:ethereum function="transfer" contract="dai">
                <ts:data>
                    <!-- to convert erc20 DAI to native xDAI, transfer to this address -->
                    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
                    <ts:uint256 ref="amount"/>
                </ts:data>
            </ts:ethereum>
        </ts:transaction>

I'm inclined to do this:

        <ts:transaction>
            <ts:ethereum>
                <ts:to   contract="dai"/>
                <ts:data function="transfer">
                    <!-- to convert erc20 DAI to native xDAI, transfer to this address -->
                    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
                    <ts:uint256 ref="amount"/>
                </ts:data>
            </ts:ethereum>
        </ts:transaction>

How do you think? Note that I used contract instead of ref as an attribute for <to> because they meant differently. One is a reference to contract; the other is a reference to an attribute.

P.S. This has to be considered together with #163

@bitcoinwarrior1
Copy link
Contributor

@colourful-land more consistent with other chains like xDAI and POA

@hboon
Copy link
Member

hboon commented Jun 3, 2019

Now outdated:

It's more consistent, but there's a change in semantics. In addition to user-defined attributes and implicit attributes, the pool of values available torefs will have to include those addresses defined in <token>/<contract>, and in the future a chainId has to be provided for lookup.

This also means that a transaction can be sent to any (untrusted) smart contract, since the to's ref might refer to an attribute.

@hboon
Copy link
Member

hboon commented Jun 3, 2019

If we use this to build a smart contract function invocation:

<ts:transaction>
            <ts:ethereum>
                <ts:to   contract="dai"/>
                <ts:data function="transfer">
                    <!-- to convert erc20 DAI to native xDAI, transfer to this address -->
                    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
                    <ts:uint256 ref="amount"/>

Does it mean that to can be specified as:

A. <ts:to ref="xxx"/> and
B. <ts:to>0x1</ts:to>

too? Or is that not allowed, which introduces an inconsistency.

Is it common for TokenScript authors to want to specify an arbitrary to for payments and function invocations?

@SmartLayer
Copy link
Author

SmartLayer commented Jun 3, 2019

If we use this to build a smart contract function invocation:
A. <ts:to ref="xxx"/> and
B. <ts:to>0x1</ts:to>

too? Or is that not allowed, which introduces an inconsistency.

I think both are allowed. I prefer to think security on a higher level than syntax. That is, instead of this:

  • building a security boundary around <contract> elements, and ignore the use of <to> 𝑘𝑛𝑜𝑤𝑖𝑛𝑔 they can only use one of the <contract> element

security should work on a higher level, like this:

  • in the case of A, if the attribute "xxx" has a value that is not one of the address assumed trusted through <contract>, then doing so will generate a security blockade at runtime.†

  • in the case of B, it only works if 0x1 happen to be defined in <contract>.

So it's not really in what syntax can you specify a value (for it to be secure), but in what we do we assert trust towards a certain value.

This does not rid the necessity of defining <contract> and use contract attribute for reference because of multi-chain and potential security tags that can be applied on a contract (e.g. a contract is trusted for data source but the TokenScript author explicitly forbid transferring money to that contract through an additional element in <contract> definition)

--
† The consequence of this design is:

  • whether or not A is secure (entire transaction not blocked by a TokenScript engine) is only known at runtime.

@hboon
Copy link
Member

hboon commented Jun 3, 2019

in the case of A, if the attribute "xxx" has a value that is not one of the address assumed trusted through , then doing so will generate a security blockade at runtime

^ This should go into a doc as one of the principles if it isn't already.

It looks much better than the one we currently have.

What if for invoking functions, we change <data> to <function>?

ie. from:

<ts:data function="transfer">
    <!-- to convert erc20 DAI to native xDAI, transfer to this address -->
    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
    <ts:uint256 ref="amount"/>
</ts:data>

to:

<ts:function name="transfer">
    <!-- to convert erc20 DAI to native xDAI, transfer to this address -->
    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
    <ts:uint256 ref="amount"/>
</ts:function>

and keep <data> for payments, where they can stick in a hex value (maybe that's another question about how it should be interpreted actually).

It'll make it clear whether it's a payment or function invocation.

Is using <function> instead of <data> too unfamiliar?

@SmartLayer
Copy link
Author

SmartLayer commented Jun 3, 2019

I have some design principles in the whole TokenScript thing which I should have properly written down in the Design Paper. Will do that. I tend to think <contract> and white-listing of web api data source is similar in the way of working so I wanted to do them together properly in the future security modelling.

Is using instead of too unfamiliar?

That's not a problem;) The problem (of using <function> in place of <data>) is that I previously (mentally) treated function attribute like packaing format. It means to prefix the data with the function's fingerprint (4-bytes).

So this

<ts:data function="transfer">
    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
    <ts:uint256 ref="amount"/>
</ts:data>

Is actually another way to express:

<ts:data>
    <function>transfer</function>
    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
    <ts:uint256 ref="amount"/>
</ts:data>

Except that it can be used with different packaging formats:

 <ts:data id="xxx">
    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
    <ts:uint256 ref="amount"/>
</ts:data>

Which allows the data to be used as a function call

<ts:data function="transfer" ref="xxx"/>

as well as an Ethereum signed message:

<ts:data signed-message="true" ref="xxx">
</ts:data>

Where the same data (can be assigned to an attribute) is re-used and packaged in a different format, instead of pre-fixing the 4-byte function code, it is prefixed with "Ethereum Signed Message" followed by a byte-count, which is implied by the signed-message attribute.

I had to admit the whole idea is immature. Actually, in 2017 I was envisioning the signed messages (like buy orders or magic links) passed around in an ASN.1 format like DER to conserve the block space, so I didn't think something like <data> has much re-use value. But ASN.1 may not be practical given the learning curve of another data serialisation tool, so it will probably be packaged in a <data> block as Ethereum has designed it (or, more objectively, hurried without design) and try to make that portable.

There are good arguments that <function> is part of data, not the packaging format of data. think this:

Imagine you have a wallet-contract that has a function which simply sends a transaction as you dictated with to, data, value tuple:

sendTransaction(address to, bytes data, (optional) uint value)

Then you can do this:

<ts:transaction>
  <ts:to ref="wallet-contract"/>
  <ts:data>
      <function>sendTransaction</function>
      <ts:data as="bytes">
          <function>transfer</function>
          <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
          <ts:uint256 ref="amount"/>
      </ts:data>
  </ts:data>
</ts:transaction>

Or this:

<ts:data id="transaction">
    <function>transfer</function>
    <ts:address>0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016</ts:address>
    <ts:uint256 ref="amount"/>
</ts:data>
....
<ts:transaction>
    <ts:to ref="wallet-contract"/>
    <ts:data>
      <function>sendTransaction</function>
      <bytes ref="transaction"/>
    </ts:data>
</ts:transaction>

In either case, function is not how data is packaged; it is data, so it goes against my statement in the beginning. Maybe there is a lot of simplicity reward if sometimes we don't use declared transactions but procedurally generated transactions.

@hboon
Copy link
Member

hboon commented Jun 4, 2019

BTW did you mean for this entire issue to be posted to https://www.tokenscript.org instead, since it's design consideration?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants