Skip to content
New issue

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

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

Already on GitHub? # to your account

[Proposal] Transfer '<<' operator #4

Open
lrettig opened this issue Aug 1, 2018 · 4 comments
Open

[Proposal] Transfer '<<' operator #4

lrettig opened this issue Aug 1, 2018 · 4 comments

Comments

@lrettig
Copy link
Collaborator

lrettig commented Aug 1, 2018

@MaxGraey proposal from lrettig/ewasm-as-wrc20#1:

For EOS smart contracts I proposed this high-level transfer operator:

function transfer(sender: Address, recipient: Address, quantity: Amount): void {
   Account.get(recipient) << quantity << Account.get(sender);
}

WDYT about this convention also for ewasm smart contracts?

@lrettig
Copy link
Collaborator Author

lrettig commented Aug 1, 2018

Cool! How do the balance checks happen? What happens if the sender balance is insufficient?

@MaxGraey
Copy link

MaxGraey commented Aug 1, 2018

You can see the details with some comments in this WAS playgound:
https://webassembly.studio/?f=tz9pgrvb7u

So in future AS it looks like:

class Account {
  constructor(
    owner: Address,
    public balance: U64,
  ) {
    this.owner = owner;
  }
  
  static get(address: Address): Account { ... }

  // [Currently]
  @operator("<<")
  static transferTo(quantity: U64, account: Account): U64 {
    assert(this.balance > quantity); // check balance
    account.balance -= quantity.value;
    return quantity;
  }

  /* Unfortunately we cannot do this now and in future
  @operator("<<")
  static transferTo(account: Account, quantity: U64): Account {
    account.balance += quantity.value;
    return account;
  }
  */

  // but in future we could do something like that
  // <----  NOT SUPPORT YET!
  @operator("<<")
  static transferTo<
     Q extends Amount | Account, 
     T extends Amount | Account
  >(a: Q, b: T): Q {
     // Handle "quantity << Account.get(from)" case
     if (a instanceof Amount && b instanceof Account) {
       assert(b.balance >= a); // check balance
       b.balance -= a;
       return <Q>a;
     }
     // Handle "Account.get(to) << quantity" case
     if (a instanceof Account && b instanceof Amount) {
       a.balance += b;
       return <Q>a;
     }
     throw new TypeError("Unsupported generic type combination");
     return <Q>0;
  }
  // ---->
}

Currently we can't overload methods with same name so for now we need U64 proxy wrapper which just boxing u64 type. That's works but require stuff like Account.get(to) << U64.wrap(quant) << Account.get(from). With simulation overloading via Generics and conditional typing if needed we can skip this wrapping. But may be we will do this better. Need more investigation.

@lrettig
Copy link
Collaborator Author

lrettig commented Aug 1, 2018

Thanks, great idea, I didn't know this sort of operator overloading was even possible with TS.

@MaxGraey
Copy link

MaxGraey commented Aug 1, 2018

Not in TS. Operator overloading valid only for AssemblyScript. It's pretty useful for math as well. You can investigate how this using for bignum (like u128, i128, u256 and etc) types for example.

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

No branches or pull requests

2 participants