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

Minor Updates #403

Merged
merged 3 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/cli/templates/base/scripts/0_deploy_faucet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Deployer, DeployFunction, Network } from '@alephium/cli'
import { Settings } from '../alephium.config'
import { TokenFaucet } from '../artifacts/ts'
import { stringToHex } from '@alephium/web3'

// This deploy function will be called by cli deployment tool automatically
// Note that deployment scripts should prefixed with numbers (starting from 0)
Expand All @@ -15,8 +16,8 @@ const deployFaucet: DeployFunction<Settings> = async (
issueTokenAmount: issueTokenAmount,
// The initial states of the faucet contract
initialFields: {
symbol: Buffer.from('TF', 'utf8').toString('hex'),
name: Buffer.from('TokenFaucet', 'utf8').toString('hex'),
symbol: stringToHex('TF'),
name: stringToHex('TokenFaucet'),
decimals: 18n,
supply: issueTokenAmount,
balance: issueTokenAmount
Expand Down
22 changes: 13 additions & 9 deletions packages/cli/templates/base/src/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Deployments } from '@alephium/cli'
import { web3, DUST_AMOUNT } from '@alephium/web3'
import { testNodeWallet } from '@alephium/web3-test'
import configuration from '../alephium.config'
import { TokenFaucet, Withdraw } from '../artifacts/ts'
import { TokenFaucet } from '../artifacts/ts'

async function withdraw() {
web3.setCurrentNodeProvider('http://127.0.0.1:22973')
Expand All @@ -20,21 +20,25 @@ async function withdraw() {
const accountGroup = account.group

// Load the metadata of the deployed contract in the right group
const deployed = deployments.getDeployedContractResult(accountGroup, 'TokenFaucet')
if (deployed === undefined) {
const faucet = deployments.getInstance(TokenFaucet, accountGroup)
if (faucet === undefined) {
console.log(`The contract is not deployed on group ${account.group}`)
continue
}
const tokenId = deployed.contractInstance.contractId
const tokenAddress = deployed.contractInstance.address
const tokenId = faucet.contractId
const tokenAddress = faucet.address
console.log(`Token faucet contract id: ${tokenId}`)
console.log(`Token faucet contract address: ${tokenAddress}`)

// Submit a transaction to use the transaction script
await Withdraw.execute(signer, {
initialFields: { token: tokenId, amount: 1n },
attoAlphAmount: DUST_AMOUNT * 2n
await faucet.transact.withdraw({
signer: signer,
attoAlphAmount: DUST_AMOUNT * 2n,
args: {
amount: 1n
},
})

const faucet = TokenFaucet.at(tokenAddress)
// Fetch the latest state of the token contract
const state = await faucet.fetchState()
console.log(JSON.stringify(state.fields, null, ' '))
Expand Down
11 changes: 6 additions & 5 deletions packages/cli/templates/base/test/token.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { web3, TestContractParams, addressFromContractId, AssetOutput, DUST_AMOUNT, groupOfAddress } from '@alephium/web3'
import { web3, TestContractParams, addressFromContractId, AssetOutput, DUST_AMOUNT, enableDebugMode } from '@alephium/web3'
import { expectAssertionError, randomContractId, testAddress, testNodeWallet } from '@alephium/web3-test'
import { deployToDevnet } from '@alephium/cli'
import { TokenFaucet, TokenFaucetTypes, Withdraw } from '../artifacts/ts'
import { TokenFaucet, TokenFaucetTypes } from '../artifacts/ts'

describe('unit tests', () => {
let testContractId: string
Expand Down Expand Up @@ -127,9 +127,10 @@ describe('integration tests', () => {

// Call `withdraw` function 10 times
for (let i = 0; i < 10; i++) {
await Withdraw.execute(signer, {
initialFields: { token: faucet.contractId, amount: 1n },
attoAlphAmount: DUST_AMOUNT * 2n
await faucet.transact.withdraw({
signer: signer,
attoAlphAmount: DUST_AMOUNT * 3n,
args: { amount: 1n }
})

const newState = await faucet.fetchState()
Expand Down
2 changes: 2 additions & 0 deletions packages/web3/src/address/address.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ describe('address', function () {
const pathInHex = '4f51cd1f0af97cf5ec9c7a3397eaeea549d55a93c216e54f2ab4a8cf29f6f865'
expect(() => subContractId(parentContractId, pathInHex, -1)).toThrow('Invalid group -1')
expect(() => subContractId(parentContractId, pathInHex, 4)).toThrow('Invalid group 4')
expect(() => subContractId('&&', pathInHex, 0)).toThrow(`Invalid parent contract ID: &&, expected hex string`)
expect(() => subContractId(parentContractId, '&&', 0)).toThrow(`Invalid path: &&, expected hex string`)
expect(subContractId(parentContractId, pathInHex, 0)).toBe(
'0e28f15ca290002c31d691aa008aa56ac12356b0380efb6c88fff929b6a26800'
)
Expand Down
8 changes: 7 additions & 1 deletion packages/web3/src/address/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { TOTAL_NUMBER_OF_GROUPS } from '../constants'
import blake from 'blakejs'
import bs58 from '../utils/bs58'
import djb2 from '../utils/djb2'
import { binToHex, concatBytes, hexToBinUnsafe } from '../utils'
import { binToHex, concatBytes, hexToBinUnsafe, isHexString } from '../utils'
import { KeyType } from '../signer'
import { MultiSig, lockupScriptCodec } from '../codec/lockup-script-codec'
import { compactSignedIntCodec } from '../codec'
Expand Down Expand Up @@ -211,6 +211,12 @@ export function subContractId(parentContractId: string, pathInHex: string, group
if (group < 0 || group >= TOTAL_NUMBER_OF_GROUPS) {
throw new Error(`Invalid group ${group}`)
}
if (!isHexString(parentContractId)) {
throw new Error(`Invalid parent contract ID: ${parentContractId}, expected hex string`)
}
if (!isHexString(pathInHex)) {
throw new Error(`Invalid path: ${pathInHex}, expected hex string`)
}
const data = concatBytes([hexToBinUnsafe(parentContractId), hexToBinUnsafe(pathInHex)])
const bytes = new Uint8Array([
...blake.blake2b(blake.blake2b(data, undefined, 32), undefined, 32).slice(0, -1),
Expand Down
13 changes: 7 additions & 6 deletions packages/web3/src/contract/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1681,10 +1681,10 @@ export async function signExecuteMethod<I extends ContractInstance, F extends Fi
): Promise<SignExecuteScriptTxResult> {
const methodIndex = contract.contract.getMethodIndex(methodName)
const functionSig = contract.contract.functions[methodIndex]
const usePreapprovedAssets = contract.contract.decodedMethods[methodIndex].usePreapprovedAssets
const methodUsePreapprovedAssets = contract.contract.decodedMethods[methodIndex].usePreapprovedAssets
const bytecodeTemplate = getBytecodeTemplate(
methodIndex,
usePreapprovedAssets,
methodUsePreapprovedAssets,
functionSig,
contract.contract.structs,
params.attoAlphAmount,
Expand Down Expand Up @@ -1716,7 +1716,7 @@ export async function signExecuteMethod<I extends ContractInstance, F extends Fi

function getBytecodeTemplate(
methodIndex: number,
usePreapprovedAssets: boolean,
methodUsePreapprovedAssets: boolean,
functionSig: FunctionSig,
structs: Struct[],
attoAlphAmount?: Number256,
Expand All @@ -1725,14 +1725,15 @@ function getBytecodeTemplate(
// For the default TxScript main function
const numberOfMethods = '01'
const isPublic = '01'
const modifier = usePreapprovedAssets ? '03' : '00'
const scriptUseApprovedAssets = attoAlphAmount !== undefined || tokens !== undefined
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: In what situations does a contract method use preapproved assets, but the script does not use preapproved assets?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's impossible, but it's possible that the method does not use preapproved assets, but the script use preapproved assets. E.g. the withdraw function of token faucet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for the explanation

const modifier = scriptUseApprovedAssets ? '03' : '00'
const argsLength = '00'
const returnsLength = '00'

const [templateVarStoreLocalInstrs, templateVarsLength] = getTemplateVarStoreLocalInstrs(functionSig, structs)

const approveAlphInstrs: string[] = getApproveAlphInstrs(usePreapprovedAssets ? attoAlphAmount : undefined)
const approveTokensInstrs: string[] = getApproveTokensInstrs(usePreapprovedAssets ? tokens : undefined)
const approveAlphInstrs: string[] = getApproveAlphInstrs(methodUsePreapprovedAssets ? attoAlphAmount : undefined)
const approveTokensInstrs: string[] = getApproveTokensInstrs(methodUsePreapprovedAssets ? tokens : undefined)
const callerInstrs: string[] = getCallAddressInstrs(approveAlphInstrs.length / 2 + approveTokensInstrs.length / 3)

// First template var is the contract
Expand Down
Loading