Cặp khoá và Ví
Làm thế nào để sinh Cặp khoá
Có rất nhiều chức năng trong các thư viện Solana để tương tác được bạn sẽ phải cần có Cặp khoá hoặc Ví. Nếu bạn đang kết nối với một ví, bạn sẽ không phải lo lắng chuyện đó nữa. Tuy nhiên, nếu bạn đang cần một Cặp khoá, bạn sẽ phải sinh ra chúng.
import { Keypair } from "@solana/web3.js";
(async () => {
let keypair = Keypair.generate();
})();
let keypair = Keypair.generate();
from solders.keypair import Keypair
keypair = Keypair()
keypair = Keypair()
use solana_sdk::signature::{Keypair};
fn main() {
let wallet = Keypair::new();
}
let wallet = Keypair::new();
$ solana-keygen new
# pubkey: 9ZNTfG4NyQgxy2SWjSiQoUyBPEvXT2xo7fKc5hPYYJ7b
solana-keygen new
Làm thế nào để phục hồi một Cặp khoá từ khoá riêng tư
Nếu bạn đã có khoá riêng tư, bạn có thể phục hồi lại cặp khoá từ khoá riêng tư đó và dùng nố để kết nối với dApp của bạn.
- Từ Bytes
import { Keypair } from "@solana/web3.js";
(async () => {
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
})();
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
from solders.keypair import Keypair
secret_key= [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_bytes(secret_key)
print("Created Keypair with Public Key: {}".format(keypair.pubkey()))
secret_key= [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_bytes(secret_key)
// clang++ keypair_from_seed.cpp -o keypair_from_seed -std=c++17 -lssl -lcrypto -lsodium
#include "solana.hpp"
using namespace many::solana;
int main() {
const uint8_t bytes[] = {
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
};
Keypair key_pair = Keypair::from_seed(bytes);
std::cout << "Created Keypair with Public Key: " << key_pair.public_key.to_base58() << std::endl;
}
const uint8_t secret_key[] = {
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
};
Keypair key_pair = Keypair::from_seed(secret_key);
use solana_sdk::signature::{Keypair, Signer};
fn main() {
let secret_key: [u8; 64] = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
];
if let Ok(wallet) = Keypair::from_bytes(&secret_key) {
let pubkey = Signer::pubkey(&wallet);
println!("Created keypair: {}", pubkey)
}
}
let secret_key: [u8; 64] = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
];
let wallet = Keypair::from_bytes(&secret_key)?;
# input your secret into the Keypath listed under solana config get
# input your secret into the Keypath listed under solana config get
- Từ chuỗi Base58
import { Keypair } from "@solana/web3.js";
import * as bs58 from "bs58";
(async () => {
const keypair = Keypair.fromSecretKey(
bs58.decode(
"5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
)
);
})();
const keypair = Keypair.fromSecretKey(
bs58.decode(
"5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
)
);
from solders.keypair import Keypair
b58_string = "5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
keypair = Keypair.from_string(b58_string)
print("Created Keypair with Public Key: {}".format(keypair.pubkey()))
b58_string = "5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
keypair = Keypair.from_string(b58_string)
use solana_sdk::signature::{Keypair, Signer};
fn main() {
let wallet = Keypair::from_base58_string(
"5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG",
);
let pubkey = Signer::pubkey(&wallet);
println!("Created keypair: {}", pubkey)
}
let wallet = Keypair::from_base58_string(
"5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG",
);
Làm thế nào để kiểm tra một cặp khoá
Nếu bạn được cho một cặp khoá, bạn có thể xác nhận rằng cặp khoá đó có khớp giữa khoá riêng tư và khoá công khai hay không.
import { Keypair, PublicKey } from "@solana/web3.js";
(async () => {
const publicKey = new PublicKey(
"24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p"
);
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
console.log(keypair.publicKey.toBase58() === publicKey.toBase58());
// true
})();
const publicKey = new PublicKey("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p");
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
console.log(keypair.publicKey.toBase58() === publicKey.toBase58());
// true
from solders.keypair import Keypair
from solders.pubkey import Pubkey
public_key = Pubkey.from_string("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p")
keys = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_bytes(keys)
print(keypair.pubkey() == public_key)
# True
public_key = Pubkey.from_string("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p")
keys = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_bytes(keys)
print(keypair.pubkey() == public_key)
# True
// clang++ verify_keypair.cpp -o verify_keypair -std=c++17 -lssl -lcrypto -lsodium
#include "solana.hpp"
using namespace many::solana;
int main() {
PublicKey public_key = PublicKey("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p");
const uint8_t bytes[] = {
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
};
Keypair key_pair = Keypair::from_seed(bytes);
std::cout << (public_key.to_base58() == key_pair.public_key.to_base58()) << std::endl;
}
PublicKey public_key = PublicKey("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p");
const uint8_t bytes[] = {
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
};
Keypair key_pair = Keypair::from_seed(bytes);
std::cout << (public_key.to_base58() == key_pair.public_key.to_base58()) << std::endl;
// 1
solana-keygen verify <PUBKEY> prompt://
solana-keygen verify <PUBKEY> prompt://
Làm thế nào để kiểm tra nếu một khoá công khai không tồn tại khoá riêng tư tương Ứng
Trong một vài trường hợp đặc biệt (ví dụ như PDA), khoá công khai sẽ không hề tồn tại khoá riêng tư tương ứng với nó. Bạn có thể kiểm tra được điều này bằng cách thử xem khoá công khai có nằm trên đường cong ed25519 hay không. Chỉ những khoá công khai nằm trên đường cong mới có khoá riêng tư, hay nói cách khác là được kiểm soát bởi một ví người dùng.
import { PublicKey } from "@solana/web3.js";
(async function () {
// Note that Keypair.generate() will always give a public key that is valid for users
const key = new PublicKey("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY"); // Valid public key
console.log(PublicKey.isOnCurve(key.toBytes())); // Lies on the ed25519 curve and is suitable for users
const offCurveAddress = new PublicKey(
"4BJXYkfvg37zEmBbsacZjeQDpTNx91KppxFJxRqrz48e"
); // Valid public key
console.log(PublicKey.isOnCurve(offCurveAddress.toBytes())); // Not on the ed25519 curve, therefore not suitable for users
const errorPubkey = new PublicKey("testPubkey"); // Is not a valid public key
})();
const key = new PublicKey("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY");
console.log(PublicKey.isOnCurve(key.toBytes()));
from solders.pubkey import Pubkey
# Note that Keypair() will always give a public key that is valid for users
key = Pubkey.from_string('5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY') # Valid public key
print(key.is_on_curve()) # Lies on the ed25519 curve and is suitable for users
off_curve_address = Pubkey.from_string('4BJXYkfvg37zEmBbsacZjeQDpTNx91KppxFJxRqrz48e') # Valid public key
print(off_curve_address.is_on_curve()) # Not on the ed25519 curve, therefore not suitable for users
error_pubkey = Pubkey.from_string("testPubkey"); # Is not a valid public key
key = Pubkey.from_string('5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY')
print(key.is_on_curve())
use solana_sdk::pubkey::{Pubkey};
use std::str::FromStr;
fn main() {
// Note that Keypair::new() will always give a public key that is valid for users
let pubkey = Pubkey::from_str("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY").unwrap(); // Valid public key
println!("{:?}", pubkey.is_on_curve()); // Lies on the ed25519 curve and is suitable for users
let off_curve_address = Pubkey::from_str("4BJXYkfvg37zEmBbsacZjeQDpTNx91KppxFJxRqrz48e").unwrap(); // Valid public key
println!("{:?}", off_curve_address.is_on_curve()); // Not on the ed25519 curve, therefore not suitable for users
let error_pubkey = Pubkey::from_str("testPubkey").unwrap(); // Is not a valid public key
}
let pubkey = Pubkey::from_str("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY").unwrap();
println!("{:?}", pubkey.is_on_curve())
Làm thế nào để sinh ra cụm mnemonic
Nếu bạn đang tạo ví, bạn sẽ cần sinh ra một cụm mnemonic để người dùng có thể lưu và phục hồi lại ví trong trường hợp cần.
import * as bip39 from "bip39";
const mnemonic = bip39.generateMnemonic();
const mnemonic = bip39.generateMnemonic();
from mnemonic import Mnemonic
mnemo = Mnemonic("english")
words = mnemo.generate(strength=256)
mnemo = Mnemonic("english")
words = mnemo.generate(strength=256)
solana-keygen new
solana-keygen new
Làm thế nào để phục hồi lại cặp khoá từ cụm mnemonic
Có rất nhiều ví sử dụng cụm mnemonics để biểu diễn khoá riêng tư. Bạn có thể chuyển đổi giữa mnemonic và cặp khoá để kiểm thử dưới môi trường địa phương.
- BIP39 - tạo một ví đơn
import { Keypair } from "@solana/web3.js";
import * as bip39 from "bip39";
(async () => {
const mnemonic =
"pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter";
const seed = bip39.mnemonicToSeedSync(mnemonic, ""); // (mnemonic, password)
const keypair = Keypair.fromSeed(seed.slice(0, 32));
console.log(`${keypair.publicKey.toBase58()}`); // 5ZWj7a1f8tWkjBESHKgrLmXshuXxqeY9SYcfbshpAqPG
})();
const mnemonic =
"pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter";
const seed = bip39.mnemonicToSeedSync(mnemonic, ""); // (mnemonic, password)
const keypair = Keypair.fromSeed(seed.slice(0, 32));
from solders.keypair import Keypair
from mnemonic import Mnemonic
mnemo = Mnemonic("english")
seed = mnemo.to_seed("pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter")
keypair = Keypair.from_bytes(seed)
print("Created Keypair with Public Key: {}".format(keypair.pubkey()))
mnemo = Mnemonic("english")
seed = mnemo.to_seed("pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter")
keypair = Keypair.from_bytes(seed)
solana-keygen recover
solana-keygen recover
- BIP44 - nhiều ví, thường được biết đến với tên gọi ví HD (Hierarchical Deterministic - Phân quyền Tất định)
Bạn có thể tạo nhiều ví từ một seed đơn và được gọi là ví HD:
import { Keypair } from "@solana/web3.js";
import { HDKey } from "micro-ed25519-hdkey";
import * as bip39 from "bip39";
(async () => {
const mnemonic =
"neither lonely flavor argue grass remind eye tag avocado spot unusual intact";
const seed = bip39.mnemonicToSeedSync(mnemonic, ""); // (mnemonic, password)
const hd = HDKey.fromMasterSeed(seed.toString("hex"));
for (let i = 0; i < 10; i++) {
const path = `m/44'/501'/${i}'/0'`;
const keypair = Keypair.fromSeed(hd.derive(path).privateKey);
console.log(`${path} => ${keypair.publicKey.toBase58()}`);
}
})();
const mnemonic =
"neither lonely flavor argue grass remind eye tag avocado spot unusual intact";
const seed = bip39.mnemonicToSeedSync(mnemonic, ""); // (mnemonic, password)
for (let i = 0; i < 10; i++) {
const path = `m/44'/501'/${i}'/0'`;
const keypair = Keypair.fromSeed(derivePath(path, seed.toString("hex")).key);
console.log(`${path} => ${keypair.publicKey.toBase58()}`);
}
solana-keygen recover 'prompt:?key=0/0'
solana-keygen recover 'prompt:?key=0/0'
Làm thế nào để sinh một địa chỉ danh nghĩa
Địa chỉ danh nghĩa, hay địa chỉ tuỳ chỉnh là những địa chỉ với các tiền tố là những ký tự cụ thể. Ví dụ, một người muốn một khoá công khai sao cho nó bắt đầu với cụm từ "elv1s", hoặc "cook". Những đại chỉ nào giúp người khác có thể biết được chủ sở hữu của khoá và thuận tiện cho việc nhận dạng hơn.
Lưu ý: Càng nhiều ký tự tiền tố trong đại chỉ danh nghĩa, sẽ càng yêu cầu nhiều thời gian tính toán hơn.
WARNING
Bạn nên sử dụng CLI cho nhiệm vụ này. Ví dụ trên Python và TypeScript chỉ nhằm mục đích minh hoạ và có hiệu suất chậm hơn rất nhiều so với CLI.
import { Keypair } from "@solana/web3.js";
(async () => {
let keypair = Keypair.generate();
while (!keypair.publicKey.toBase58().startsWith("elv1s")) {
keypair = Keypair.generate();
}
})();
let keypair = Keypair.generate();
while (!keypair.publicKey.toBase58().startsWith("elv1s")) {
keypair = Keypair.generate();
}
from solders.keypair import Keypair
keypair = Keypair()
while(str(keypair.pubkey())[:5]!="elv1s") :
keypair = Keypair()
print("Created Keypair with Public Key: {}".format(keypair.pubkey()))
keypair = Keypair()
while(str(keypair.pubkey())[:5]!="elv1s") :
keypair = Keypair()
// clang++ vanity_keypair.cpp -o vanity_keypair -std=c++17 -lssl -lcrypto -lsodium
#include "solana.hpp"
using namespace many::solana;
int main() {
auto key_pair = Keypair::generate();
while (key_pair.public_key.to_base58().substr(0, 5) != "elv1s") {
key_pair = Keypair::generate();
}
std::cout << "Created Keypair with Public Key: " << key_pair.public_key.to_base58() << std::endl;
}
auto key_pair = Keypair::generate();
while (key_pair.public_key.to_base58().substr(0, 5) != "elv1s") {
key_pair = Keypair::generate();
}
solana-keygen grind --starts-with e1v1s:1
solana-keygen grind --starts-with e1v1s:1
Làm thế nào ký và kiểm tra tinh nhắn bằng ví
Một chức năng cơ bản của một cặp khoá là ký một tin nhắn và cho phép kiểm tra chữ ký cùng tin nhắn đó. Wuas trình xác nhận một chữ ký cho phép người nhận chắc chắn rằng dữ liệu được ký là do chủ sở hữu thực sự của cặp khoá ký lên.
Để làm được điều đó chúng ta cần sử dụng thư viện mật mã học TweetNaCl.
import { Keypair } from "@solana/web3.js";
import nacl from "tweetnacl";
import { decodeUTF8 } from "tweetnacl-util";
(async () => {
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
const message = "The quick brown fox jumps over the lazy dog";
const messageBytes = decodeUTF8(message);
const signature = nacl.sign.detached(messageBytes, keypair.secretKey);
const result = nacl.sign.detached.verify(
messageBytes,
signature,
keypair.publicKey.toBytes()
);
console.log(result);
})();
const message = "The quick brown fox jumps over the lazy dog";
const messageBytes = decodeUTF8(message);
const signature = nacl.sign.detached(messageBytes, keypair.secretKey);
const result = nacl.sign.detached.verify(
messageBytes,
signature,
keypair.publicKey.toBytes()
);
console.log(result);
from solders.keypair import Keypair
secret_key = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138, 189, 224, 216, 117,
173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240,
121, 121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_bytes(secret_key)
message = b"The quick brown fox jumps over the lazy dog"
signature = keypair.sign_message(message)
verify_sign = signature.verify(keypair.pubkey(), message)
print(verify_sign) # bool
message = b"The quick brown fox jumps over the lazy dog"
signature = keypair.sign_message(message)
verify_sign = signature.verify(keypair.pubkey(), message)
print(verify_sign) # bool
Làm thế nào để kết nối ví
Thư viện wallet-adapter của Solana sẽ giúp cho việc quản lý và kết nối ví trở nên hết sức đơn giản.
React
Chạy đoạn mã bên dưới để cài đặt các thư viện cần thiết:
yarn add @solana/wallet-adapter-react @solana/wallet-adapter-react-ui @solana/wallet-adapter-base @solana/wallet-adapter-wallets
Thư viện React wallet-adapter cho phép lập trình viên duy trì kết nối cũng như truy cập vào các trạng thái của ví thông qua Hook
và Context Provider
như useWallet
, WalletProvider
, useConnection
, và ConnectionProvider
. Ứng dụng React phải được bọc bởi WalletProvider
và ConnectionProvider
.
Ngoài ra, lập trình viên cũng có thể hiển thị kết nối đến người dùng bằng cách sử dụng useWalletModal
để mở một cửa sổ thông báo. Lưu ý, bạn cần phải bọc toàn bộ ứng dụng bằng WalletModalProvider
từ thư viện @solana/wallet-adapter-react-ui
. Cửa sổ kết nối sẽ xử lý tất cả các bước kết nối nên chúng ta chỉ cần lắng nghe sự kiện kết nối ví thành công. useWallet
sẽ trả về giá trị khác rỗng là wallet
nếu kết nối thành công. Ngược lại, nó sẽ trả về rỗng nếu kết nối chưa thành công hoặc người dùng đã ngắt kết nối.
import React, { useMemo, FC, PropsWithChildren } from "react";
import {
ConnectionProvider,
WalletProvider,
} from "@solana/wallet-adapter-react";
import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
import {
LedgerWalletAdapter,
PhantomWalletAdapter,
SlopeWalletAdapter,
TorusWalletAdapter,
} from "@solana/wallet-adapter-wallets";
import { clusterApiUrl } from "@solana/web3.js";
import { useWallet } from "@solana/wallet-adapter-react";
import { useWalletModal } from "@solana/wallet-adapter-react-ui";
import { MouseEventHandler } from "react";
export const Web3Provider: FC<PropsWithChildren<{}>> = ({ children }) => {
// Can be set to 'devnet', 'testnet', or 'mainnet-beta'
const endpoint = useMemo(
() => clusterApiUrl(WalletAdapterNetwork.Devnet),
[]
);
// @solana/wallet-adapter-wallets includes all the adapters but supports tree shaking --
// Only the wallets you configure here will be compiled into your application
const wallets = useMemo(
() => [
new PhantomWalletAdapter(),
new SlopeWalletAdapter(),
new TorusWalletAdapter(),
new LedgerWalletAdapter(),
],
[]
);
return (
<ConnectionProvider endpoint={endpoint}>
<WalletModalProvider>
<WalletProvider wallets={wallets}>{children}</WalletProvider>
</WalletModalProvider>
</ConnectionProvider>
);
};
/**
* Make sure to wrap the App with
* ConnectionProvider, WalletProvider, and WalletModalProvider.
*
* If you have a lot of Providers already, you can combine them
* into a single wrapper (i.e. Web3Provider) instead.
*/
export const App = () => {
return (
<Web3Provider>
<AppChild />
</Web3Provider>
);
};
const AppChild = () => {
const { wallet } = useWallet();
const { setVisible } = useWalletModal();
// Display the connection modal
const onRequestConnectWallet = () => {
setVisible(true);
};
// Prompt user to connect wallet
if (!wallet) {
return <button onClick={onRequestConnectWallet}>Connect Wallet</button>;
}
return (
<main>
<p>Wallet successfully connected!</p>
<p>{wallet.publicKey.toString()}</p>
</main>
);
};
const { wallet } = useWallet();
const { setVisible } = useWalletModal();
const onRequestConnectWallet = () => {
setVisible(true);
};
// Prompt the user to connect their wallet
if (!wallet) {
return <button onClick={onRequestConnectWallet}>Connect Wallet</button>;
}
// Displays the connected wallet address
return (
<main>
<p>Wallet successfully connected!</p>
<p>{wallet.publicKey.toBase58()}</p>
</main>
);
Vue
Chạy đoạn mã sau đây để cài các thư viện cần thiết:
npm install solana-wallets-vue @solana/wallet-adapter-wallets
Plugin Solana Wallets Vue cho phép chúng ta khởi tạo một vùng nhớ cho ví và tạo một thuộc tính $wallet
mới với phạm vi toàn cục. Thuộc tính này có thể được truy cập ở bất kỳ một thành phần nào. Tất cả các thuộc tính và phương thức bạn có thể lấy từ useWallet()
đều được trình bày ở đây. Chúng ta cũng cần cài và hiển thị thành phần WalletMultiButton
để cho phép người dùng có thể chọn ví cũng như kết nối ví.
<script setup>
import { WalletMultiButton } from "solana-wallets-vue";
import {
LedgerWalletAdapter,
PhantomWalletAdapter,
SlopeWalletAdapter,
TorusWalletAdapter,
} from "@solana/wallet-adapter-wallets";
import { initWallet, useWallet } from "solana-wallets-vue";
const wallets = {
wallets: [
new PhantomWalletAdapter(),
new SlopeWalletAdapter(),
new TorusWalletAdapter(),
new LedgerWalletAdapter(),
],
};
initWallet(wallets);
const { connected, wallet } = useWallet();
</script>
<template>
<div>
<p v-if="connected">
Wallet with public key {{ wallet.publicKey }} successfully connected!
</p>
<div v-else>
<wallet-multi-button></wallet-multi-button>
</div>
</div>
</template>
<script setup>
import { WalletMultiButton } from "solana-wallets-vue";
</script>
<template>
<wallet-multi-button></wallet-multi-button>
</template>
Svelte
Chạy đoạn mã sau đây để cài các thư viện cần thiết:
npm install @svelte-on-solana/wallet-adapter-core @svelte-on-solana/wallet-adapter-ui @solana/wallet-adapter-base @solana/wallet-adapter-wallets @solana/web3.js
Gói Svelte Wallet Adapter cho phép thêm một Svelte Store ($walletStore
) có khả năng truy xuất từ các tập tin JS, TS or/and Svelte bên trong dự án được tạo từ Svelte Template hoặc SvelteKit. Sử dụng mã nguồn tham khảo tại đây bạn có thể sử dụng bộ tiếp hợp cho SSR và cả SPA. Gói giao diện người dùng có chứa một thành phần là <WalletMultiButton />
, nó cho phép người dùng có thể chọn và tạo kết nối đến ví.
<script>
import { walletStore } from "@svelte-on-solana/wallet-adapter-core";
import {
WalletProvider,
WalletMultiButton,
ConnectionProvider,
} from "@svelte-on-solana/wallet-adapter-ui";
import { clusterApiUrl } from "@solana/web3.js";
import {
PhantomWalletAdapter,
SolflareWalletAdapter,
TorusWalletAdapter,
LedgerWalletAdapter,
} from "@solana/wallet-adapter-wallets";
const localStorageKey = "walletAdapter";
const network = clusterApiUrl("devnet"); // localhost or mainnet
let wallets = [
new PhantomWalletAdapter(),
new SolflareWalletAdapter(),
new TorusWalletAdapter(),
new LedgerWalletAdapter(),
];
</script>
<WalletProvider {localStorageKey} {wallets} autoConnect />
<ConnectionProvider {network} />
{#if $walletStore?.connected} Wallet with public key {$walletStore.publicKey}
successfully connected! {:else}
<WalletMultiButton />
{/if}
<script>
import { walletStore } from "@svelte-on-solana/wallet-adapter-core";
import { WalletMultiButton } from "@svelte-on-solana/wallet-adapter-ui";
</script>
{#if $walletStore?.connected} Wallet with public key {$walletStore.publicKey}
successfully connected! {:else}
<WalletMultiButton />
{/if}