Skip to content

Commit

Permalink
feat: add unsigned equivalent of make contract deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
ahsan-javaid authored and reedrosenbluth committed Nov 19, 2021
1 parent f5d8ece commit 792c2ae
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 10 deletions.
40 changes: 30 additions & 10 deletions packages/transactions/src/builders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
publicKeyToAddress,
pubKeyfromPrivKey,
publicKeyFromBuffer,
createStacksPublicKey,
} from './keys';

import { TransactionSigner } from './signer';
Expand Down Expand Up @@ -672,12 +673,10 @@ export async function makeSTXTokenTransfer(
/**
* Contract deploy transaction options
*/
export interface ContractDeployOptions {
export interface BaseContractDeployOptions {
contractName: string;
/** the Clarity code to be deployed */
codeBody: string;
/** a hex string of the private key of the transaction sender */
senderKey: string;
/** transaction fee in microstacks */
fee?: IntegerType;
/** the transaction nonce, which must be increased monotonically with each new transaction */
Expand All @@ -696,6 +695,16 @@ export interface ContractDeployOptions {
sponsored?: boolean;
}

export interface ContractDeployOptions extends BaseContractDeployOptions {
/** a hex string of the private key of the transaction sender */
senderKey: string;
}

export interface UnsignedContractDeployOptions extends BaseContractDeployOptions {
/** a hex string of the public key of the transaction sender */
publicKey: string;
}

/**
* @deprecated Use the new {@link estimateTransaction} function insterad.
*
Expand Down Expand Up @@ -761,6 +770,23 @@ export async function estimateContractDeploy(
*/
export async function makeContractDeploy(
txOptions: ContractDeployOptions
): Promise<StacksTransaction> {
const privKey = createStacksPrivateKey(txOptions.senderKey);
const stacksPublicKey = getPublicKey(privKey);
const publicKey = publicKeyToString(stacksPublicKey);
const unsignedTxOptions: UnsignedContractDeployOptions = { ...txOptions, publicKey };
const transaction: StacksTransaction = await makeUnsignedContractDeploy(unsignedTxOptions);

if (txOptions.senderKey) {
const signer = new TransactionSigner(transaction);
signer.signOrigin(privKey);
}

return transaction;
}

export async function makeUnsignedContractDeploy(
txOptions: UnsignedContractDeployOptions
): Promise<StacksTransaction> {
const defaultOptions = {
fee: BigInt(0),
Expand All @@ -775,8 +801,7 @@ export async function makeContractDeploy(
const payload = createSmartContractPayload(options.contractName, options.codeBody);

const addressHashMode = AddressHashMode.SerializeP2PKH;
const privKey = createStacksPrivateKey(options.senderKey);
const pubKey = getPublicKey(privKey);
const pubKey = createStacksPublicKey(options.publicKey);

let authorization = null;

Expand Down Expand Up @@ -827,11 +852,6 @@ export async function makeContractDeploy(
transaction.setNonce(txNonce);
}

if (options.senderKey) {
const signer = new TransactionSigner(transaction);
signer.signOrigin(privKey);
}

return transaction;
}

Expand Down
62 changes: 62 additions & 0 deletions packages/transactions/tests/builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as fs from 'fs';
import {
makeUnsignedSTXTokenTransfer,
makeContractDeploy,
makeUnsignedContractDeploy,
makeContractCall,
makeStandardSTXPostCondition,
makeContractSTXPostCondition,
Expand Down Expand Up @@ -630,6 +631,67 @@ test('Make smart contract deploy', async () => {
expect(serialized).toBe(tx);
});

test('Make smart contract deploy unsigned', async () => {
const contractName = 'kv-store';
const codeBody = fs.readFileSync('./tests/contracts/kv-store.clar').toString();
const publicKey = '03797dd653040d344fd048c1ad05d4cbcb2178b30c6a0c4276994795f3e833da41';
const fee = 0;
const nonce = 0;

const authType = AuthType.Standard;
const addressHashMode = AddressHashMode.SerializeP2PKH;
const transaction = await makeUnsignedContractDeploy({
contractName,
codeBody,
publicKey,
fee,
nonce,
network: new StacksTestnet(),
anchorMode: AnchorMode.Any
});

const serializedTx = transaction.serialize();

const bufferReader = new BufferReader(serializedTx);
const deserializedTx = deserializeTransaction(bufferReader);

expect(deserializedTx.auth.authType).toBe(authType);

expect(deserializedTx.auth.spendingCondition!.hashMode).toBe(addressHashMode);
expect(deserializedTx.auth.spendingCondition!.nonce!.toString()).toBe(nonce.toString());
expect(deserializedTx.auth.spendingCondition!.fee!.toString()).toBe(fee.toString());
});

test('Make smart contract deploy signed', async () => {
const contractName = 'kv-store';
const codeBody = fs.readFileSync('./tests/contracts/kv-store.clar').toString();
const senderKey = 'e494f188c2d35887531ba474c433b1e41fadd8eb824aca983447fd4bb8b277a801';
const fee = 0;
const nonce = 0;

const authType = AuthType.Standard;
const addressHashMode = AddressHashMode.SerializeP2PKH;
const transaction = await makeContractDeploy({
contractName,
codeBody,
senderKey,
fee,
nonce,
network: new StacksTestnet(),
anchorMode: AnchorMode.Any
});

const serializedTx = transaction.serialize();

const bufferReader = new BufferReader(serializedTx);
const deserializedTx = deserializeTransaction(bufferReader);
expect(deserializedTx.auth.authType).toBe(authType);

expect(deserializedTx.auth.spendingCondition!.hashMode).toBe(addressHashMode);
expect(deserializedTx.auth.spendingCondition!.nonce!.toString()).toBe(nonce.toString());
expect(deserializedTx.auth.spendingCondition!.fee!.toString()).toBe(fee.toString());
});

test('Make contract-call', async () => {
const contractAddress = 'ST3KC0MTNW34S1ZXD36JYKFD3JJMWA01M55DSJ4JE';
const contractName = 'kv-store';
Expand Down

1 comment on commit 792c2ae

@vercel
Copy link

@vercel vercel bot commented on 792c2ae Nov 19, 2021

Choose a reason for hiding this comment

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

Please sign in to comment.