Before we start
Back to basics
Hedera's take on the basics
ECDSA and EdDSA based authorisation + Demo
ThresholdKey
// generate keys
const edKey = PrivateKey.generateED25519();
const ecKey = PrivateKey.generateECDSA();
// create a `ThresholdKey` that represents a 1 of 2 multisig threshold
const multisigPublicKeys = [edKey.publicKey, ecKey.publicKey];
const multisigKeyList = new KeyList(multisigPublicKeys, 1);
// Update account to use this `KeyList`, via an `AccountUpdateTransaction`.
// This replaces the single signature with a the 1 of 2 multisig
const makeMultisigTx = new AccountUpdateTransaction()
.setAccountId(multisigAccountId)
.setKey(multisigKeyList)
.freezeWith(client);
const makeMultisigTxSignedByOneKey = await makeMultisigTx.sign(edKey);
const makeMultisigTxSubmitted = await makeMultisigTxSignedByOneKey.execute(client);
// Sign a `TransferTransaction` using the ECDSA key only,
// then attempt to execute it
const transfer1of2EcTx = new TransferTransaction()
.addHbarTransfer(multisigAccountId, new Hbar(-34))
.addHbarTransfer(operatorId, new Hbar(34))
.freezeWith(client);
const transfer1of2EcTxSigned = await transfer1of2EcTx.sign(ecKey);
const transfer1of2EcTxSubmitted = await transfer1of2EcTxSigned.execute(client);
Account abstraction on Ethereum /1
Account abstraction on Ethereum /2
Account abstraction on Ethereum /3
Account abstraction on Ethereum /4
What is account abstraction? /1
What is account abstraction? /2
What is account abstraction? /3
Smart contract based authorisation
SC based authorisation + Demo
ThresholdKey
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "./IHederaTokenService.sol";
contract Account {
IHederaTokenService hederaTokenService;
constructor() {
hederaTokenService = IHederaTokenService(address(0x0167));
}
function performPrecompileOperation(
address token,
address sender,
address recipient,
int64 amount
) external {
int64 responseCode = hederaTokenService.transferToken(
token, sender, recipient, amount);
// HederaResponseCodes.SUCCESS = 22
require(responseCode == 22, "HTS transfer error");
}
}
// Create a `ThresholdKey` that represents a 1 of 2 multisig threshold
// where one of the keys is the smart contract ID, and the other is the ECDSA key
const multisigPublicKeys = [scId, ecKey.publicKey];
const multisigKeyList = new KeyList(multisigPublicKeys, 1);
// Update account to use this `KeyList`, via an `AccountUpdateTransaction`.
// This replaces the single signature with a the 1 of 2 multisig
const makeMultisigTx = new AccountUpdateTransaction()
.setAccountId(multisigAccountId)
.setKey(multisigKeyList)
.freezeWith(client);
const makeMultisigTxSignedByAllKeys = await makeMultisigTx.sign(ecKey);
const makeMultisigTxSubmitted = await makeMultisigTxSignedByAllKeys.execute(client);
// Invoke `Account.performPrecompileOperation` function on the smart contract whose ID is
// of the `KeyList` of the multisig account
const scPerformPrecompileTx = new ContractExecuteTransaction()
.setContractId(scId)
.setGas(400_000)
.setFunction(
'performPrecompileOperation',
new ContractFunctionParameters()
.addAddress(toLongZeroEvmAddress(htsFtId))
.addAddress(multisigAccountEvmAddress.toString())
.addAddress(toLongZeroEvmAddress(operatorId))
.addInt64(23),
)
.freezeWith(client);
// NOTE that this transaction is intentionally **unsigned**.
// This is to verify that the smart contract is also part of `KeyList` of the multisig account
// does indeed fulfil its role in being able to authenticate the precompile transaction in lieu of a signature.
const scPerformPrecompileTxSubmitted = await scPerformPrecompileTx.execute(client);
Enabling AA on an EVM-compatible network /1
Enabling AA on an EVM-compatible network /2
What's needed?
hederaAccountService
system contractisAuthorized(address, messageHash, signatureBlob)
isAuthorizedCurrentTransaction()
Enabling AA on an EVM-compatible network /3