Skip to content
This repository has been archived by the owner on Sep 30, 2021. It is now read-only.

[Question] Create Smart Contract call transaction offline and submit it later #367

Open
evgeny-s opened this issue Jan 14, 2021 · 6 comments

Comments

@evgeny-s
Copy link

Hey, guys.
Thanks for this useful lib.
Is it a possibility to create a Smart Contract call offline, wrap it to string let's say, share a transaction string (for example put it to DB), and later unwrap and submit it to the Blockchain?

Thanks!

@emostov
Copy link
Contributor

emostov commented Jan 15, 2021

Hey 👋

I am actually not personally familiar with transactions for contracts, but if they are standard transactions (extrinsics), you can encode the transaction, which turns it into a SCALE encoded hex string.

You can store that hex string in a DB, and you can store it at various stages of construction and should still be able to decode it with polkadot-js and/or the utils from this lib to sign etc. Additionally, polkadot-js is pretty flexible when it comes into reading data so in many cases it can also read in a JSON representation of the transaction.

The final transaction is broadcasted as a hex string so you could easily store that in a DB as well and broadcast it as is.

@azhu003
Copy link

azhu003 commented May 11, 2021

Hi.

Have you implemented the offline creation contract call?

@evgeny-s
Copy link
Author

Hello, @azhu003
Yes, I was able to do it using extrinsics and polkadot JS lib. Here is the example:

    this.appKeyring = keyring.addFromJson(
      JSON.parse(process.env.APP_WALLET_JSON)
    );

    const gasLimitAuto = -1;
    const anyValue = 0;
    const transferObj = await this.contract.tx.methodName(
      anyValue,
      gasLimitAuto,
      param1,
      param2,
      param3,
      param4,
      param5
    );

    return new Promise((res, rej) => {
      transferObj
        .signAndSend(this.appKeyring, ({ status }) => {
          if (status.isInBlock) {
            const hash = status.asInBlock.toHex();
            this.logger.log(`In block: ${hash}`);
            res(hash);
          }
        })
        .catch((err) => rej(err));
    });

@evgeny-s
Copy link
Author

Above - online call.
Below offline:

public async createSignedTransaction(
    privateKey: string,
    destination: string,
    amount: string,
  ): Promise<SignedDataResponse> {
    const gasLimitAuto = -1;
    const anyValue = 0;

    const keyring = new Keyring({type: this.userKeyRingType});
    const userKeyRing = keyring.addFromSeed(hexToU8a(privateKey));

    const tx = await this.contract.tx
      .transfer(anyValue, gasLimitAuto, destination, Number(amount), partialFee)
      .signAsync(userKeyRing);
    const txString = JSON.stringify(tx);
    const signedDataDto = new SignedDataResponse();
    signedDataDto.tx = txString;

    return signedDataDto;
  }


public async submitTx(tx: string, publicKey: string, appId: string): Promise<SubmitTransactionRes> {
    const txn = JSON.parse(tx);

    const txnHash = await this.substrateApi.rpc.author.submitExtrinsic(txn);
    const txnString = JSON.stringify(txnHash);
    const submitTxResponse = new SubmitTransactionRes(txnString);

    this.logger.log(`Tx hash: ${txnHash}`);

    return submitTxResponse;
  }

@evgeny-s
Copy link
Author

evgeny-s commented May 11, 2021

@azhu003
Hope it helps.

@azhu003
Copy link

azhu003 commented May 11, 2021

@evgeny-s thanks😁

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

No branches or pull requests

3 participants