흐름에 구축 | FCL 배우기 - 14. 개인 키로 트랜잭션에 서명하여 체인 상태를 변경하는 방법
21702 단어 onflowjavascriptfcltutorial
머리말
지난번에는 브라우저에서 편안하게 Lilico 및 Blocto 지갑으로 거래에 서명하는 방법을 다루었습니다. 그러나 브라우저를 사용할 수 없는 백엔드(예: 서버 측)에서 동일한 작업을 수행해야 하는 경우가 매우 일반적입니다.
친구여, 이것이 바로 우리가 당신에게 가르칠 것이므로 두려워하지 마십시오. 이 문서의 자료를 통해 작업한 후 다음 방법을 알게 됩니다.
multisig
프로세스1단계 - 설치
"@onflow/fcl"
, elliptic
및 sha3
패키지를 프로젝트 종속성으로 추가합니다.2단계 - 서명자 만들기
새 파일을 만들고 이름을 지정해 보겠습니다
signer.js
. 파일은 아무 이름이나 가질 수 있으며 여기서는 의미론적 의미가 있는 것을 선택합니다. 서명자는 3가지 기능이 필요합니다.hashMessageHex
라고 합니다. SHA3 algorithm을 사용하여 트랜잭션 메시지를 해시하는 데 사용됩니다. 우리가 SHA3를 사용하는 이유는 이전 기사 중 하나에서 설명한 Testnet Faucet에서 계정 생성 중에 Hash Algorithm
로 선택했기 때문입니다.기능 자체는 매우 간단합니다. 특별히 압축되고 16진수 문자열로 표시된 트랜잭션 메시지를
update
에 의해 노출된 SHA3
메서드에 공급한 다음 digest
메서드에서 결과를 반환합니다.const hashMessageHex = (msgHex) => {
const sha = new SHA3(256);
sha.update(Buffer.from(msgHex, "hex"));
return sha.digest();
};
signWithKey
를 호출합니다. 이를 사용하여 개인 키로 해시된 거래 메시지에 서명합니다. 이제 이것은 정말 복잡한 주제이며 이것을 단순히 복사하여 붙여넣고 나중에 암호 연구를 수행하면 많은 코너를 잘라낼 것이라고 가정해 봅시다, mkey? 😅tldr: 서명을 생성하기 위해 Elliptic Curve Digital Signature Algorithm을 사용합니다.
const signWithKey = (privateKey, msgHex) => {
const key = curve.keyFromPrivate(Buffer.from(privateKey, "hex"));
const sig = key.sign(hashMessageHex(msgHex));
const n = 32;
const r = sig.r.toArrayLike(Buffer, "be", n);
const s = sig.s.toArrayLike(Buffer, "be", n);
return Buffer.concat([r, s]).toString("hex");
};
signer
함수로, 서명할 사용자의 정보를 생성하는 Authorization Function 함수와 이 정보를 사용하여 서명을 생성하는 signing function
함수로 사용됩니다.export const signer = async (account) => {
// We are hard coding these values here, but you can pass those values from outside as well.
// For example, you can create curried function:
// const signer = (keyId, accountAdddress, pkey) => (account) => {...}
// and then create multiple signers for different key indices
const keyId = Number(0); // always ensure that your keyId is a number not a string
const accountAddress = "0x5593df7d286bcdb8";
const pkey =
"248f1ea7b4a058c39dcc97d91e6a5d0aa7afbc931428561b6efbc7bd0f5e0875";
// authorization function need to return an account
return {
...account, // bunch of defaults in here, we want to overload some of them though
tempId: `${accountAddress}-${keyId}`, // tempIds are more of an advanced topic, for 99% of the times where you know the address and keyId you will want it to be a unique string per that address and keyId
addr: sansPrefix(accountAddress), // the address of the signatory, currently it needs to be without a prefix right now
keyId // this is the keyId for the accounts registered key that will be used to sign, make extra sure this is a number and not a string
// This is where magic happens! ✨
signingFunction: async (signable) => {
// Singing functions are passed a signable and need to return a composite signature
// signable.message is a hex string of what needs to be signed.
const signature = await signWithKey(pkey, signable.message);
return {
addr: withPrefix(accountAddress), // needs to be the same as the account.addr but this time with a prefix, eventually they will both be with a prefix
keyId, // needs to be the same as account.keyId, once again make sure its a number and not a string
signature // this needs to be a hex string of the signature, where signable.message is the hex value that needs to be signed
};
}
};
};
✨Please, note, that
signingFunction
is asynchronous, meaning that it can use Promises inside of its body to get a signature out of extension or remote server. Which is super handy, when you want to handle gas fees for your users 😉
3단계 - FCL 설정
import { config, query, mutate, tx } from "@onflow/fcl";
import { signer } from "./signer"
// Contrary to our wallet signing example, we don't need most of it in our config now
// so we'll get back to simple version
config({
"accessNode.api": "https://rest-testnet.onflow.org",
"0xBasic": "0xafabe20e55e9ceb6"
});
4단계 - readCounter 구현
완전히 동일하게 작동하기 때문에 이전 기사에서 동일한 기능을 복사합니다.
const readCounter = async () => {
const cadence = `
import Basic from 0xBasic
pub fun main():UInt{
return Basic.counter
}
`;
const counter = await query({ cadence });
console.log({ counter });
};
5단계 - shiftCounter 구현
shiftCounter
함수도 거의 동일합니다. 유일한 차이점은 이번에는 signer
함수를 사용하여 모든 역할을 채울 것이라는 것입니다. 또한 console.time
및 console.timeEnd
메서드를 사용하여 트랜잭션을 봉인하는 데 걸린 시간을 기록합니다.const shiftCounter = async (value) => {
console.log("%cSigning Transaction", `color: teal`);
// Our Cadence code. Notice the use of alias here
const cadence = `
import Basic from 0xBasic
transaction(shift: UInt8){
prepare(signer: AuthAccount){
Basic.incrementCounterBy(shift)
}
}
`;
// List of arguments
const args = (arg, t) => [arg(value.toString(), t.UInt8)];
const proposer = signer;
const payer = signer;
const authorizations = [signer];
// "mutate" method will return us transaction id
const txId = await mutate({
cadence,
args,
proposer,
payer,
authorizations,
limit: 999
});
console.log(`Submitted transaction ${txId} to the network`);
console.log("%cWaiting for transaction to be sealed...", `color: teal`);
const label = "Transaction Sealing Time";
console.time(label);
// We will use transaction id in order to "subscribe" to it's state change and get the details
// of the transaction
const txDetails = await tx(txId).onceSealed();
console.timeEnd(label);
return txDetails;
};
드디어
파일 끝에 IIFE를 추가하고 방금 정의한 메서드로 채우겠습니다.
(async () => {
console.clear();
await readCounter();
const txDetails = await shiftCounter(12);
console.log({ txDetails });
// we will call "readCounter" function second time to ensure
// that value of counter has changed
await readCounter();
})();
먼지가 가라앉은 후 콘솔의 출력이 비슷해야 합니다.
{counter: "655"}
Signing Transaction
Submitted transaction d88e98687dd98f7597aca9afaf3daaba788f644f90003c9b144bfa13440fd9ab to the network
Waiting for transaction to be sealed...
Transaction Sealing Time: 14749.60000000149ms
{txDetails: Object}
{counter: "667"}
결국 그렇게 어렵지는 않았죠? 😉
다음 시간까지! 👋
자원
전체 소스 코드 - https://codesandbox.io/s/dev-to-14-mutate-with-pkey-d0jsj0
패키지 - SHA3 - https://www.npmjs.com/package/sha3
패키지 - 타원형 - https://www.npmjs.com/package/elliptic
FCL - 인증 기능 - https://docs.onflow.org/fcl/reference/api/#authorization-function
유용할 수 있는 기타 리소스:
Flow Docs 사이트 - https://docs.onflow.org/ - Flow 블록체인 및 상호 작용 방법에 대한 자세한 정보
Flow Portal - https://flow.com/ - Flow 진입점
FCL JS - https://github.com/onflow/fcl-js - 소스 코드 및 FCL JS 라이브러리에 기여하는 기능
케이던스 - https://docs.onflow.org/cadence/ - 케이던스 소개
Codesandbox - https://codesandbox.io - 빠른 프로토타이핑을 지원하는 놀라운 브라우저 내 IDE
Reference
이 문제에 관하여(흐름에 구축 | FCL 배우기 - 14. 개인 키로 트랜잭션에 서명하여 체인 상태를 변경하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/onflow/build-on-flow-learn-fcl-14-how-to-mutate-chain-state-by-signing-transactions-with-a-private-key-5c4p텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)