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

In smart contracts, AENS delegated signature problem #1983

Closed
sunbx opened this issue May 10, 2024 · 5 comments
Closed

In smart contracts, AENS delegated signature problem #1983

sunbx opened this issue May 10, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@sunbx
Copy link
Contributor

sunbx commented May 10, 2024

This is used in historical contracts for example

AENS.transfer(owner, Contract.address, name, signature = sig)

In this case, how should JS-SDK 13.3.2 use the get signature file call?

this is my code:

image

image

image

@sunbx sunbx added the bug Something isn't working label May 10, 2024
@nikita-fuchs
Copy link
Contributor

@davidyuk should know !

@davidyuk
Copy link
Member

AENS.transfer still works, but signature format changed since Ceres.

As far as we all in Ceres the best to use signDelegation method of Account or AeSdk.

The error you have is because aepp-calldata expects to get signature as hex string or Buffer, but sdk encodes it as sg_. So, you need to decode signature before passing to calldata. Related issue: aeternity/aepp-calldata-js#240

Here is example of changing name owner via delegation signature in Ceres using the [email protected]

import {
  Node, AeSdk, MemoryAccount, CompilerHttp, DelegationTag, packDelegation, decode,
} from '@aeternity/aepp-sdk';

const [owner, recipient] = [MemoryAccount.generate(), MemoryAccount.generate()];
console.log('Owner address', owner.address);
console.log('Recipient address', recipient.address);

const aeSdk = new AeSdk({
  accounts: [owner],
  nodes: [{ name: 'testnet', instance: new Node('https://testnet.aeternity.io') }],
  onCompiler: new CompilerHttp('https://v7.compiler.aepps.com'),
});

await fetch(`https://faucet.aepps.com/account/${owner.address}`, { method: 'POST' });

const name = `test-name-${Date.now()}.chain`;
await aeSdk.aensClaim(name, 0);
console.log('Claimed name', name);
console.log('Name owner', (await aeSdk.aensQuery(name)).owner);

const contractSourceCode = `
contract DelegateTest =
  stateful entrypoint transfer(
    owner: address, new_owner: address, name: string, sign: signature): unit =
    AENS.transfer(owner, new_owner, name, signature = sign)
`;
const contract = await aeSdk.initializeContract({ sourceCode: contractSourceCode });
const contractAddress = (await contract.$deploy([])).address;
console.log('Contract deployed at', contractAddress);

const delegation = packDelegation({
  tag: DelegationTag.AensName, accountAddress: aeSdk.address, contractAddress, nameId: name,
});
const delegationSignature = decode(await aeSdk.signDelegation(delegation));
await contract.transfer(owner.address, recipient.address, name, delegationSignature);
console.log('Name transferred');

console.log('Name owner', (await aeSdk.aensQuery(name)).owner);

@sunbx
Copy link
Contributor Author

sunbx commented May 16, 2024

I tried to use the method you provided to call, but still failed

Is there something wrong? I did not find it....

image

image

image

@davidyuk
Copy link
Member

A private key exposed in the above message, ensure that you don't have much funds there!

I figured out the issue. Contracts deployed in Iris are executed in FATE v2, so it expects an old signature format. The problem is that we have security concerns about that format, and I would like to drop its support in future SDK versions. Is it feasible to migrate your contracts to FATE v3?

Meanwhile, you can provide consensusProtocolVersion: ConsensusProtocolVersion.Iris option to generate an old signature in Ceres using AeSdk::signNameDelegationToContract. See the below reproduction.

The code I've used to test it
import {
  Node, AeSdk, MemoryAccount, CompilerHttp, ConsensusProtocolVersion, decode,
} from '@aeternity/aepp-sdk';

const [owner, recipient] = [
  new MemoryAccount('9ebd7beda0c79af72a42ece3821a56eff16359b6df376cf049aee995565f022f840c974b97164776454ba119d84edc4d6058a8dec92b6edc578ab2d30b4c4200'),
  MemoryAccount.generate(),
];
console.log('Owner address', owner.address);
console.log('Recipient address', recipient.address);

const aeSdk = new AeSdk({
  accounts: [owner],
  nodes: [{ name: 'testnet', instance: new Node('http://localhost:3013') }],
  onCompiler: new CompilerHttp('https://v7.compiler.aepps.com'),
});

const contractSourceCode = `
contract DelegateTest =
  stateful entrypoint transfer(
    owner: address, new_owner: address, name: string, sign: signature): unit =
    AENS.transfer(owner, new_owner, name, signature = sign)
`;
const contract = await aeSdk.initializeContract({ sourceCode: contractSourceCode });
const contractAddress = (await contract.$deploy([])).address;
console.log('Contract deployed at', contractAddress);
console.log('Height', await aeSdk.getHeight());
console.log('Consensus', ConsensusProtocolVersion[(await aeSdk.api.getNodeInfo()).consensusProtocolVersion]);

const name = `test-name-${Date.now()}.chain`;
const nameObj = await aeSdk.aensPreclaim(name);
await nameObj.claim();
console.log('Claimed name', name);
console.log('Name owner', (await aeSdk.aensQuery(name)).owner);

console.log('Height', await aeSdk.getHeight());
console.log('Consensus', ConsensusProtocolVersion[(await aeSdk.api.getNodeInfo()).consensusProtocolVersion]);
const delegationSignature = await aeSdk.signNameDelegationToContract(
  contractAddress,
  name,
  { consensusProtocolVersion: ConsensusProtocolVersion.Iris },
);
console.log('delegationSignature', delegationSignature);
const delegationSignatureAsHex = decode(delegationSignature);
await contract.transfer(owner.address, recipient.address, name, delegationSignatureAsHex);
console.log('Name transferred');

console.log('Name owner', (await aeSdk.aensQuery(name)).owner);
dev_mode:
  auto_emit_microblocks: true

chain:
  persist: false
  hard_forks:
    "1": 0
    "5": 1
    "6": 2
  genesis_accounts:
    ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E: 10000000000000000000000

So, the contract deployed in Iris and called in Ceres.

@sunbx
Copy link
Contributor Author

sunbx commented May 20, 2024

@davidyuk Thank you for your answer. I will upgrade the contract to FATE V3. Then there will be no problem

@sunbx sunbx closed this as completed May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants