Если вы еще не являетесь участником Medium и хотите получить полный доступ к моим историям, воспользуйтесь этой ссылкой, чтобы подписаться на членство в Medium. Ваш членский взнос напрямую поддерживает меня и побуждает писать больше качественных материалов в будущем. Здоровья!
Всем привет! Добро пожаловать в мое четвертое прохождение этой серии. В этом посте мы продолжим рассказывать о том, как построить простую систему подписки пользователей на Solana Web3.
Предполагается, что вы закончили первые 3 поста этой серии, прежде чем начать этот. Если нет, то посмотрите предыдущие 2 поста:
Учебное пособие по Full Stack Solana Web3 (1) — подключение к фантомному кошельку
Full Stack Solana Web3 Tutorial (2) — Сделайте свой первый платеж
Full Stack Solana Web3 Tutorial (3) — Простая система подписки пользователей
Если вы закончили, давайте начнем!
Изменение выборки JSON
В предыдущем отрывке мы использовали JSON для получения нашего открытого ключа в серверную часть, чтобы проверить, подписан ли пользователь. Теперь, поскольку нам также нужно обновить метод подписки пользователя, мы немного изменим наше правило JSON Fetch.
В предыдущем случае наш JSON выглядит следующим образом:
{pubkey: <your_pub_key>}
Теперь мы бы изменили что-то вроде этого:
{pubkey: <your_pub_key>, method: "r"}
Если метод «r», это означает, что мы читаем данные. Это также может быть «w», что указывает на то, что передаваемый публичный ключ будет обновлен в базе данных. Теперь давайте изменим нашу функцию checksub
в index.html
на ниже:
async function checksubs(){ const url = '/'; const header = { 'Content-Type': 'application/json' }; const data = { pubkey: pubKey.toString(), method:"r"}; const res = await fetch(url,{ method: 'POST', cache: 'no-cache', headers: header, body: JSON.stringify(data) }); const result = await res.json(); return result; }
Как и в случае с checksubs, он всегда просто считывает данные. Итак, мы бы поместили метод: «r» здесь. Кроме того, чтобы улучшить читаемость, я изменил вызов результата, используя await
вместо .then
в предыдущем посте.
Теперь, в app.js
, мы должны изменить app.post()
примерно так:
app.post('/', (req, res) => { console.log('Got body:', req.body.pubkey); if (req.body.method=="r"){ pub_key = req.body.pubkey; con.query('SELECT * FROM users WHERE pubkey = ?', [pub_key], function (err, results, fields) { if (Object.keys(results).length>0){ res.status(200).json({'result' : 'True'}); }else{ res.status(200).json({'result' : 'False'}); } }); } });
Проверка статуса подписки в интерфейсе
Итак, теперь наш бэкэнд вернет, подписан ли публичный адрес пользователя. Теперь давайте изменим connectWallet()
в index.html
так, как показано ниже:
async function connectWallet(){ const isPhantomInstalled = window.solana && window.solana.isPhantom try { const resp = await window.solana.connect(); pubKey = resp.publicKey; var greeting_p = document.createElement("p"); var message = document.createTextNode("hi! Your wallet"+pubKey.toString()+" is connected"); greeting_p.appendChild(message); document.getElementById("greet").appendChild(greeting_p); var result = await checksubs(); if (result.result=="False"){ not_subscribed(); }if (result.result=="True"){ subscribed(); } } catch (err) { console.log(err); } }
Теперь что мы делаем, так это проверяем, возвращает ли бэкэнд True или False. Если False, вызовите функцию not_subscribed()
. В противном случае вызывается функция subscribed()
. Теперь давайте посмотрим, как выглядят эти две функции:
function subscribed(){ var subscribed_p = document.createElement("p"); var subscribed_message = document.createTextNode("you are subscribed!"); subscribed_p.appendChild(subscribed_message); document.getElementById("greet").appendChild(subscribed_p); } function not_subscribed(){ var not_subscribed_p = document.createElement("p"); var not_subscribed_message = document.createTextNode("you are not subscribed!"); not_subscribed_p.appendChild(not_subscribed_message); document.getElementById("greet").appendChild(not_subscribed_p); var btn = document.createElement("button"); btn.innerHTML = "Subscribe Now!"; btn.addEventListener("click", transferSOL); document.getElementById("greet").appendChild(btn); }
Итак, в subscribed()
мы просто печатаем вы подписаны в интерфейсе. В not_subscribed()
мы напечатаем вы не подписаны, а также кнопку, которая вызывает функцию transferSOL()
, о которой мы упоминали в предыдущем посте.
Теперь в функцию transferSOL()
мы можем добавить функцию, которая также извлекает JSON для добавления открытого ключа пользователя после успешной оплаты SOL:
async function transferSOL(){ const transferTransaction = new web3.Transaction().add(web3.SystemProgram.transfer({ fromPubkey: pubKey, toPubkey: new web3.PublicKey("FVv5Dtmreiz9TPnU71tkXVZAPZhasYXujHk2QTehSBPJ"), lamports: 10000000 })) const network = "https://api.devnet.solana.com"; const connection = new web3.Connection(network); transferTransaction.feePayer = pubKey; let blockhash = (await connection.getLatestBlockhash("finalized")).blockhash; transferTransaction.recentBlockhash = blockhash; const {signature} = await window.solana.signAndSendTransaction(transferTransaction); console.log("test"); await connection.confirmTransaction(signature); console.log(signature); const url = '/'; const header = { 'Content-Type': 'application/json' }; const data = { pubkey: pubKey.toString(), method:"w", signature: signature}; const res = await fetch(url,{ method: 'POST', cache: 'no-cache', headers: header, body: JSON.stringify(data) }); const result = await res.json(); }
Итак, в приведенном выше коде вы можете видеть, что помимо открытого ключа пользователя мы также получаем подпись в нашем бэкэнде для проверки. Итак, в бэкенде нам нужно проверить, есть ли подпись и т. Д. Итак, в app.js
мы теперь исправим что-то вроде следующего:
app.post('/', async function (req, res){ console.log('Got body:', req.body.pubkey); if (req.body.method=="r"){ pub_key = req.body.pubkey; con.query('SELECT * FROM users WHERE pubkey = ?', [pub_key], function (err, results, fields) { if (Object.keys(results).length>0){ res.status(200).json({'result' : 'True'}); }else{ res.status(200).json({'result' : 'False'}); } }); }else if (req.body.method=="w"){ establishConnection(); console.log(req.body.signature); const transactionDetails = await connection.getParsedTransaction(req.body.signature); pub_key = transactionDetails.transaction.message.instructions[0].parsed.info.source; if (transactionDetails.transaction.message.instructions[0].parsed.info.destination=="FVv5Dtmreiz9TPnU71tkXVZAPZhasYXujHk2QTehSBPJ"&&transactionDetails.transaction.message.instructions[0].parsed.info.lamports=="10000000"){ con.query('INSERT INTO `users`(pubkey) VALUES (?);', [pub_key], function (err, result) { if (err) throw err; console.log("record inserted"); res.status(200).json("sucess!"); }); } }else{ console.log("something wrong!"); } });
Итак, здесь нам нужно установить соединение с сетью Solana. Итак, ставим все это под establishConnection()
. Код в функции прост. Теперь давайте посмотрим, что под app.js:
- Во-первых, когда мы получаем выборку из внешнего интерфейса, нам нужно определить его метод «w» или «r». Если «r», запустите часть, чтобы проверить, подписан ли пользователь.
- Если это «w», мы устанавливаем соединение с Solana и находим детали транзакции, используя
getParsedTransaction()
. Мы передали подпись get from frontend, чтобы продолжить; - Затем, используя
transactionDetails.transaction.message.instructions[0].parsed.info.destination
, вы сможете извлечь пункт назначения потока средств. Затем, используяtransactionDetails.transaction.message.instructions[0].parsed.info.lamports
, вы сможете извлечь сумму перевода средств по транзакции. Используя эти 2 информации, убедитесь, что достаточное количество лампорта переведено на учетную запись назначения; - Теперь обновите открытый ключ пользователя в базе данных SQL. Помнить! Используйте
transactionDetails.transaction.message.instructions[0].parsed.info.source
для извлечения открытого ключа, чтобы добавить список подписанных пользователей.
Заключение
Итак, теперь, если вы следуете вышеизложенному, нажмите «подписать пользователя» через интерфейс и подтвердите транзакцию. Теперь обновите снова. Вы увидите что-то вроде b ниже:
Поздравляю! Вы успешно создали систему подписки вашего первого пользователя. Если вы хотите узнать больше о разработке web3 в Solana. Пожалуйста, следите за обновлениями и увидимся в следующий раз!