Solana, Anchor 및 React 탐색기를 사용한 파생 주소(PDA)
23520 단어 solanareactprogrammingcrypto
testnet
의 환경(수도꼭지/공중투하)에 문제가 있는 것 같습니다.선택기에서 devnet
를 선택하거나 기본값이기 때문에 변경하지 마십시오.지갑을 지향devnet
네트워크로 바꾸는 것을 잊지 마세요.주: 이 게시물의 모든 코드를 찾을 수 있습니다here.본문의 개념을 보여주는 시범here이 있다.
용례
다음 장면을 상상해 봅시다.사용자가 만들거나 주조한 기호화폐를 사용하는 dApp을 만들었습니다.테스트 목적에서 사용자가 스스로 영패를 공중으로 던지는 것을 허용하기를 원합니다. (테스트 환경에서)문제는 당신이 기호화폐를 주조했으니 더 많은 기호화폐를 주조하거나 양도할 권리가 있는 사람이 바로 당신입니다.이것은 당신이 이 조폐소와 거래하는 모든 거래에 서명해야 한다는 것을 의미한다.
또 다른 상황은 사용자가 다른 사용자와 어떤 상품을 교환하기를 원한다는 것이다.안전을 위해 거래된 물품은 특정한 임시 계좌(제3자 위탁 관리 계좌)에 넣고 제3자에게만 발급해야 하며 그들은 견적을 받아들일 수 있다.어려움은 위탁 관리 계좌가 사용자에게 속하면 그들이 기호화폐를 발급하기 위해 거래를 비준/서명해야 한다는 것이다.우리는 사용자가 프로젝트의 발표에 직접 참여하는 것을 원하지 않는다.
이 두 가지 상황에서 우리는 프로그램 소유자를 대표하여 거래에 서명할 수 있는'대리'가 필요하다.이를 위해서는 프로그램 파생 주소(PDA)가 필요합니다.
내가 위에서 묘사한 장면에서 우리는 사용해야 한다Cross-Program Invocations.이 두 가지 상황에서 우리는 Token Program와 상호작용을 할 것이다.공중 투하 상황에서 우리는
mint
더 많은 기존 기호화폐를 사용자에게 주고 두 번째 상황에서 우리는 transfer
기호화폐를 줄 것이다.이 두 가지 상황에서 PDA는 우리를 대표하여 이 거래에 서명할 권리가 있다.
PDA의 정의
이 계정들은 프로그램이 가지고 있으며 다른 계정과 달리 개인 키의 통제를 받지 않는다.
Pubkey::create_program_address
이러한 주소를 생성합니다.이 메서드는 프로그램 ID 해싱 피드를 사용하여 새 32바이트 주소를 만듭니다.변화(50%)가 있는데 이것은 ed25519 곡선의 점일 수 있다.이것은 이 주소와 연결된 개인 키가 있다는 것을 의미합니다.이 경우 Solana 프로그래밍 모델의 안전성이 손상될 수 있습니다.생성된 주소가 ed25519 곡선에 있으면 Pubkey::create_program_address
실패합니다.일을 간소화하기 위해 방법
Pubkey::find_program_address
은 필요에 따라 여러 번create_program_address
을 호출하여 우리가 효과적인 방법을 찾을 때까지 한다.내부 작업 중인 PDA
PDA를 더 탐색하기 위해 농장 동물 거래 앱을 개발하기로 했다.네가 거래하는 동물은 기호화폐다.이 응용 프로그램에서 PDA는 두 가지 다른 사용 방식을 가지고 있다.첫 번째 방식은 위탁 계좌다.사용자는 그들이 제공한 지폐를 저장한다.만약 다른 사용자가 요약을 받아들이거나 요약을 발기한 사용자가 요약을 취소하기로 결정한다면 이 기호화폐는 방출될 것이다.이 두 가지 상황에서 계좌 자체는 목적지로의 이동에 서명할 권리가 있다.
주의: 코드 세션에 대해, 나는 관련 부분만 표시하고, 환매 프로토콜의 줄 번호를 연결할 것입니다.모든 코드를 찾을 수 있습니다.
여기 있다 계좌를 대신 관리하다.
우선, 우리는 주소를 내보내야 한다.이것은 우리의 위탁 계좌 가 될 것이다.
const offer = anchor.web3.Keypair.generate();
const [escrowedTokensOfOfferMaker, escrowedTokensOfOfferMakerBump] = await anchor.web3.PublicKey.findProgramAddress(
[offer.publicKey.toBuffer()],
program.programId
)
우리는 요철을 저장해서, 이렇게 하면 호출 findProgrammAddress
방법을 통해 그것을 다시 계산할 필요도, 앞쪽에서 아래로 전달할 필요도 없다.contract / program
에서는 이렇게 사용합니다code. 전체 파일을 찾을 수 있습니다.여기서 견적을 작성하고 있습니다. anchor_spl::token::transfer(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
anchor_spl::token::Transfer {
from: ctx
.accounts
.token_account_from_who_made_the_offer
.to_account_info(),
to: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
authority: ctx.accounts.who_made_the_offer.to_account_info(),
},
),
im_offering_this_much,
)
우리는 가격을 제시한 계좌에서 위탁 관리 계좌로 기호화폐를 옮기고 있다.얼마나 옮길지 지정했어.이때 우리는 오퍼를 받아들이거나 취소할 수 있다.취소의 경우here:
// Transfer what's on the escrowed account to the offer reciever.
anchor_spl::token::transfer(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
anchor_spl::token::Transfer {
from: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
to: ctx
.accounts
.where_the_escrowed_account_was_funded_from
.to_account_info(),
authority: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
},
&[&[
ctx.accounts.offer.key().as_ref(),
&[ctx.accounts.offer.escrowed_tokens_of_offer_maker_bump],
]],
),
ctx.accounts.escrowed_tokens_of_offer_maker.amount,
)?;
// Close the escrow account
anchor_spl::token::close_account(CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
anchor_spl::token::CloseAccount {
account: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
destination: ctx.accounts.who_made_the_offer.to_account_info(),
authority: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
},
&[&[
ctx.accounts.offer.key().as_ref(),
&[ctx.accounts.offer.escrowed_tokens_of_offer_maker_bump],
]],
))
우리는 이 혜택을 발기한 계좌로 기호화폐를 보내고 있다.거래에 서명한 기구는 PDA입니다. 왜냐하면 기호화폐를 가지고 있기 때문입니다.우리도 더 이상 필요하지 않기 때문에 대리 관리 계좌를 닫고 있다.마지막 관련 부분은 요약을 받은 기호화폐의'교환'이다.
// Transfer token to who started the offer
anchor_spl::token::transfer(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
anchor_spl::token::Transfer {
from: ctx
.accounts
.account_holding_what_receiver_will_give
.to_account_info(),
to: ctx
.accounts
.account_holding_what_maker_will_get
.to_account_info(),
authority: ctx.accounts.who_is_taking_the_offer.to_account_info(),
},
),
ctx.accounts.offer.amount_received_if_offer_accepted,
)?;
// Transfer what's on the escrowed account to the offer reciever.
anchor_spl::token::transfer(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
anchor_spl::token::Transfer {
from: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
to: ctx
.accounts
.account_holding_what_receiver_will_get
.to_account_info(),
authority: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
},
&[&[
ctx.accounts.offer.key().as_ref(),
&[ctx.accounts.offer.escrowed_tokens_of_offer_maker_bump],
]],
),
ctx.accounts.escrowed_tokens_of_offer_maker.amount,
)?;
// Close the escrow account
anchor_spl::token::close_account(CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
anchor_spl::token::CloseAccount {
account: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
destination: ctx.accounts.who_made_the_offer.to_account_info(),
authority: ctx
.accounts
.escrowed_tokens_of_offer_maker
.to_account_info(),
},
&[&[
ctx.accounts.offer.key().as_ref(),
&[ctx.accounts.offer.escrowed_tokens_of_offer_maker_bump],
]],
))
우리가 이렇게 하는 것은 세 가지 절차다.우선, 우리는 원하는 토큰을 제시 가격을 제시한 사용자에게 보낼 것입니다.그리고 우리는 위탁 지폐를 요약을 받는 사용자에게 이전할 것이다.그리고 지난번에 캡처한 것과 같이, 우리는 더 이상 필요하지 않기 때문에 대리 계정을 닫을 것입니다.섹션 공중 투하
응용 프로그램에서 PDA를 사용하는 또 다른 방법은 공중 투과입니다.이런 상황에서 우리는 사용자가 우리가 가지고 있는 유한한 수량의 물건(기호화폐)을 스스로 조폐(공중투하)할 수 있도록 허락하기를 희망한다.이러한 상황에서 PDA는 우리가 새 기호화폐의 주조에 서명하는 것을 대표할 권리가 있다.
이전과 마찬가지로 우리는
findProgramAddress
를 사용하여 PDA를 획득했습니다. const cowSeed = Buffer.from(anchor.utils.bytes.utf8.encode("cow-mint-faucet"));
const pigSeed = Buffer.from(anchor.utils.bytes.utf8.encode("pig-mint-faucet"));
const [cowMintPda, cowMintPdaBump] = await anchor.web3.PublicKey.findProgramAddress(
[cowSeed],
program.programId);
const [pigMintPda, pigMintPdaBump] = await anchor.web3.PublicKey.findProgramAddress(
[pigSeed],
program.programId);
띄우기 코드는 다음과 같이 간략화됩니다. anchor_spl::token::mint_to(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
anchor_spl::token::MintTo {
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.destination.to_account_info(),
authority: ctx.accounts.mint.to_account_info(),
},
&[&[&mint_seed, &[mint_bump]]],
),
amount,
)?;
이전과 마찬가지로 여기서 주의해야 할 가장 중요한 점은 PDA 자체가 거래에 서명할 권리가 있다는 것이다.종합하다.
프레젠테이션 어플리케이션 이 구축되었습니다.
devnet
및 testnet
모두 애플리케이션을 구축했습니다.페이지의 선택기를 사용하여 둘 사이를 변경할 수 있습니다. (만약 이렇게 한다면 가리키는 네트워크를 변경하는 것을 기억하십시오.)만약 네가 SOL이 없다면, 너는 좀 공중 투하할 수 있다.이 밖에 농장 동물들을 공수해 거래를 시작할 수 있소.
주의: 20초 간격으로 나는 모든 사용자가 사용할 수 있는 완전한 제품 목록을 표시하기 위해 체인 밖 데이터베이스로 끌어올릴 것이다.
여기 있다 마지막 생각.
이것은 소라나의 또 하나의 재미있는 실험이다.나는 모든 물건을 체인에 유지하고 싶었지만, 결국은 모든 사용자가 그것을 사용할 수 있도록 체인 밖의 데이터베이스를 얻었다.나는 모든 혜택을 체인점에 두는 것을 탐색할 것이다.
전반적으로 나는 소라나와 함께 노는 시간을 즐겼다.나는 계속 실험을 하고 보고할 것이다.다음까지.
리소스
Reference
이 문제에 관하여(Solana, Anchor 및 React 탐색기를 사용한 파생 주소(PDA)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/fndomendez/exploring-program-derive-addresses-pdas-with-solana-anchor-and-react-19bm텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)