伊恩编写了一个区块链应用程序

注:本公告转载/翻译自 Pi Network 官网,原文(英文版)发布于2024年4月10日。

:作者是一位业余开发者,希望探索并记录在树莓派平台上创建 Web3 应用的过程。本文生动地展现了他开发树莓派应用的历程,并详细分解了开发步骤。即使是经验不足的开发者,也能从中了解到构建树莓派应用是多么简单直观。

请尽情阅读这篇引人入胜的文章。开发者们,快来看看如何快速地将您的应用推广给数千万 Pi 社区成员!欲了解更多信息,请点击此处查看 Pi 平台的正式文档,以及点击此处查看全面的社区开发者指南。

语言,以及他所谓的“噱头”,均为作者本人所为。读者请自行斟酌。

面向初学者的逐步指南,教你如何在树莓派平台上进行开发

我以前也尝试过Python开发,但水平还是很差。Pi区块链,我来了!开始吧! 

如果你想直接跳到步骤详解,我会很遗憾,但我能理解。以下是目录:

简介
认识你的开发者
我开发的内容
我使用的工具
关于 Pi SDK

实际操作步骤:
搭建 Python 环境
;构建 Python 应用;
在 Pi 上注册新应用;
获取 Pi API 密钥;
将 Python 应用与 Pi 集成
;运行 Pi 沙箱;
设置支付处理;
使用身份验证

一些调试
笔记,Ian 风格


或者,您可以从这里获取最终应用程序的所有代码:https://github.com/pi-apps/insult-o-meter。 

我之前尝试编程的经历……简直糟糕透了。敷衍了事,半途而废。总之,各种问题都有。 

所以,当我决定在Pi平台上编写一个区块链应用程序并创建一个入门指南时,我开始冒冷汗。天哪,我想。又要来了。

剧透预警:我惊喜地发现,这过程相当有趣。以下是我用Pi构建区块链应用程序的详细步骤指南。

你需要什么

要跟着步骤操作,或者直接获取我的代码并自行研究,你需要:

  • 具备一定的 Python 3.0 知识
  • 具备足够的 JavaScript 知识,能够更改页面上的文本
  • 具备足够的 JavaScript 知识,能够复制粘贴代码而不破坏任何内容。
  • iPhone 或安卓设备

与您的开发人员见面

我是:

  • 我是一个非常非常非常业余的Python开发者。安装库的时候我还是会搞不清楚状况。我在ChatGPT上最常遇到的问题是:“这段代码有什么问题?”
  • 一个更加业余的JavaScript开发者。实际上,除了从Medium教程里复制粘贴的内容之外,我对JavaScript一窍不通。
  • 一位从业28年的数字营销人员,大脑可塑性正在下降

另外,我不懂开发者的术语。对我来说,“token”(令牌)就像我上世纪90年代坐地铁时用的那种东西。所以,如果我偶尔说“那个API的东西”,请见谅。我会举些例子,希望你能明白。

我建造的

我考虑过做一些简单的、有益身心的,或者既简单又有益身心的事情。

不。

隆重推出“侮辱计量器”。只需 0.01 PiCoin,即可获得三种创意十足的侮辱语录,随时可用:

伊恩编写了一个区块链应用程序

相信我,这很符合品牌形象。

我使用的工具

我使用了:

所有操作都在我可靠的Macbook Pro上完成,运行的是Sonoma系统。

关于 Pi SDK

Pi SDK 可以将你的应用连接到所有现有的 Pi 货币。真正的加密货币爱好者可能会因为我的这个比喻而揍我,但 SDK 就像你商店里的信用卡终端。

它的运作方式如下:

  1. 当有人访问你的页面时,Pi 会启动整个流程。SDK 会连接到你的应用,确认用户已授予访问其 Pi 钱包的权限等等。如果你的应用是一家实体店,这就好比你打开灯、解锁大门一样。
  2. 检查是否有未付清的款项。这件事很难找到合适的比喻。千万别忘了这一步。我就是忘了,结果吃了大亏。
  3. 耐心等待顾客进行操作。你可能在柜台后面,也可能在店内走动,一边整理货架上的商品,一边等待顾客浏览。
  4. 创建付款。Pi 设置交易的方式与您向客户索取信用卡信息的方式相同。
  5. 然后,后台会进行一系列操作。你已经刷了信用卡。支付信息会发送给支付服务提供商,他们会验证信用卡号,检查余额,如果余额充足,就会将款项从客户转给你。
  6. 返回状态。最后,Pi 说:“好了,全部完成。你已经获得金币了!”

设置 Python 环境

如果你像我一样不是 Python 专家(咳咳),以下是我搭建环境的方式:

  1. 打开终端
  2. 运行 pipenv shell。这会创建一个封闭的环境,让我可以在一个隔离的环境中安全地进行各种尝试。如果你还没用过,可以点击这里查看。市面上还有其他虚拟环境工具,但这个工具用起来比较简单。
  3. 安装上述库

就是这样。

构建 Python 应用程序

我就不赘述细节了。我用 Flask 后端搭建了一个简单的网页。这个应用会从一个文本文件中读取侮辱性词语,随机抓取一个,然后用一些基本的 JavaScript 代码将其传递给网页。 

目前,我们只是在构建应用程序,尚未连接 SDK。这意味着只有三种路由:

  • /get_quote会从文本文件中随机抓取一条名言。它不会连接到树莓派,而是连接到一段 JavaScript 代码,用于统计请求的名言数量。如果用户请求的名言超过三条,这段 JavaScript 代码会显示一个模态框,其中包含一个按钮,点击该按钮即可跳转到批准路由。
  • 背面很无聊

很简单。当然,你也可以做得更复杂一些。

请务必记下应用网址:

伊恩编写了一个区块链应用程序

在树莓派上安装应用程序时需要用到它。

在 Pi 上注册你的新应用

如果有详细的步骤说明,这很容易。我乐于助人,所以这里是详细步骤:

注意:您将使用两个应用程序:Pi Browser(一款基于 Pi 平台的网页浏览器)和 Pi Mining App(用于获取所有 Pi 资源)。您需要在两者之间来回切换。这可能会让您有点抓狂,但从长远来看,这是值得的。一旦您习惯了,工作流程就会变得更加轻松。相信我,我不会误导您。

1. 获取 Pi Mining 应用程序

在进行任何其他操作之前,您需要安装 Pi Mining App。这是一个可以在您的 iPhone 或 Android 设备上运行的小巧应用程序。请从以下位置获取:

Google Play 商店:https://play.google.com/store/apps/details ?id =com.blockchainvault,或 

App Store:https://itunes.apple.com/us/app/pi-network/id1445472541

它还可以让你挖掘Pi币。无需GPU。

请便,我等。

准备就绪?进入下一步。

2. 获取 Pi 浏览器

接下来,您需要下载 Pi 浏览器,这是一款移动网络浏览器,可让您访问所有使用 Pi SDK 构建的应用程序。 

Google Play 商店:https://play.google.com/store/apps/details?id  =pi.browser

苹果应用商店:https://apps.apple.com/us/app/pi-browser/id1560911608 

一切就绪。

3. 注册您的应用

打开 Pi 应用。

图片[3]-伊恩编写了一个区块链应用程序-OKPi派导航

输入你的应用名称和描述。我使用Pi 测试网作为应用网络。我绝对不会尝试在真实网络上发布这个东西。而且,测试网的交易是 100% 纯正的模拟 Pi 交易,所以你不会因为一个有 bug 的应用而向任何人收费。我建议你也这样做。

您应该会看到这个方便的屏幕:

伊恩编写了一个区块链应用程序

该清单显示了您在主网上发布应用程序的过程中所处的阶段。

现在,我们需要设置一个钱包。

4. 创建/连接钱包

应用钱包就是你的银行账户(某种程度上)。你需要创建一个并关联一个账户。 

  1. 在应用的开发者门户页面上,点击   钱包
  2. 然后点击应用钱包>生成新钱包

更多奇妙的事情将会发生。

完成后,你可能需要点击 Pi 浏览器中的后退按钮。我就是这么做的。

现在您可以将钱包连接到此应用程序。点击 (如有必要)选择钱包,然后选择要连接的钱包。

砰!你就拥有了一个应用程序和一个钱包。

5. 配置应用程序

返回应用开发者门户页面,点击  配置

  1. 根据需要设置可见性。我将其设置为公开。
  2. 应用托管设置为“自托管” 。
  3. 除非你真的很有勇气,准备将应用发布到全世界,否则请将应用的网址留空。
  4. “应用开发 URL”中,输入 Flask 在终端中显示的地址(参见上文“构建 Python 应用”)。对我来说,它是http://127.0.0.1:8080
  5. (可选)输入您的隐私政策等链接网址。目前可以留空。

注意:别耍小聪明在开发环境的 URL 中使用 https。我试过了,结果看到了一个难过的表情:

伊恩编写了一个区块链应用程序

我返回并重置到http://127.0.0.1:3000 ,一切就都正常了。

获取您的 Pi API 密钥

点击 API密钥

小菜一碟。千万别弄丢了。

将 Python 应用程序与 Pi 集成

这真的很难。

开玩笑的,开玩笑的。很简单。只需将以下代码添加到你的 Python 应用的 HTML 代码中:

Javascript
<script src="https://sdk.minepi.com/pi-sdk.js"></script>
<script> Pi.init({ version: "2.0", sandbox: true }) </script>

注意:只有当您的应用程序在 Pi Sandbox 中运行时,  sandbox 标志才为“true” 。

然后添加以下内容。它用于验证用户身份:

 Javascript
<script> 
    // Authenticate the user, and get permission to request payments from them:
    const scopes = ['payments'];

    // Read more about this callback in the SDK reference:
    function onIncompletePaymentFound(payment) { 
        paymentId = payment.identifier
        txid = payment.transaction.txid
        $.post('/payment/complete',
                {
                    paymentId: paymentId,
                    txid: txid,
                    debug: 'cancel'
                }
            )
    };

    Pi.authenticate(scopes, onIncompletePaymentFound).then(function(auth) {
console.log('woot!');
    }).catch(function(error) {
      console.error(error);
    });
</script>

最后,将以下代码添加到你的 Flask app.py 文件中:

Python
header = {
    'Authorization': "Key YOUR-API-KEY"
}

这样就将您的 API 密钥提供给了 SDK。请注意安全使用变量。

运行 Pi Sandbox

事情变得有点复杂了。“有点”的意思是“伊恩搞糊涂了”,这并不难理解。

沙盒环境允许您在不将应用程序暴露给全世界的情况下开发应用程序、测试交易等等。它是一个封装层,将 Python 应用程序连接到 SDK,同时确保所有内容都得到很好的隔离。

  1. 请确保你的开发机器上运行着 Python 应用。
  2. 在浏览器中,访问https://sandbox.minepi.com/app/[应用名称] 。将所有空格替换为短横线。例如,我的应用名称是https://sandbox.minepi.com/app/the-insult-o-matic
  3. 你会看到一个授权界面。
  4. 拿起你的手机。在 Pi Mining 应用中,点击  汉堡菜单并选择Pi Utilities
  5. 在“实用工具”屏幕上,滚动到最底部,然后单击“授权沙盒”。
  6. 输入浏览器中显示的代码,然后点击“继续”。

胜利!首次加载应用时,您应该会看到以下内容:

伊恩编写了一个区块链应用程序

注意:这假设您已经拥有一个 Pi 账户,并且账户里有少量 Pi 币,您应该有。毕竟,您已经安装了 Pi Mining 应用和 Pi Browser。

目前耗时:不足 2 小时(含宠物照护)

不算编写 Python 应用,我只是:

  1. 设置 Pi 钱包
  2. 开始挖 Pi 矿(为什么不呢?)
  3. 设置应用程序
  4. 我喂了猫。这时她变得非常不耐烦了。
  5. 已具备与 Pi 区块链集成所需的一切条件
  6. 遛狗了。它像个正在进行如厕训练的幼儿一样蹦蹦跳跳的。
  7. 在狗狗把泥巴带进屋里之前,我先把它的爪子擦干了。
  8. 我阻止了我的狗在卧室里把我的猫逼到角落,否则猫会把它活活剥皮。
  9. 我的应用已经在树莓派沙盒环境中运行了。

把步骤写出来花了更多时间。

你的速度可能比这位X世代程序员快。如果你说你用了不到一个小时,我会说你是在炫耀。

设置支付处理

这才是“真正的”工作。之所以加引号,是因为一旦你掌握了方法,其实很简单。我稍后会一步一步地讲解。现在,只需粘贴这段代码:

1. 将此代码添加到您的 HTML 页面

将以下代码粘贴到 Pi.init 代码之后:

 Javascript
<script>
    // we're doing payments
    const Pi = window.Pi;
    // main payments function
    function createPayment() {
        const paymentData = {
            amount: .01,
            memo: "This buys you three more insults! What a deal!!!",
            metadata: { insultid: 123456 }
        };
        // the SDK does all this like magic
        const paymentCallbacks = {
            onReadyForServerApproval: (paymentDTO) => {
                paymentId = paymentDTO
                $.post('/payment/approve', {
                    paymentId: paymentId,
                    accessToken: accessToken
                })
            },
            onReadyForServerCompletion: (paymentDTO, txid) => {
                paymentId = paymentDTO
                txid = txid
                $.post('/payment/complete',
                        {
                            paymentId: paymentId,
                            txid: txid,
                            debug: 'complete'
                        }
                    )
            },
            onCancel: (paymentDTO) => {
                paymentId = paymentDTO.identifier
                $.post('/payment/complete',
                        {
                            paymentId: paymentId,
                            debug: 'cancel'
                        }
                    )
            },
            onError: (paymentDTO) => {
                console.log('There was an error ', paymentDTO)
                paymentId = paymentDTO.identifier
                $.post('/payment/error',
                        {
                            paymentDTO: paymentDTO,
                            paymentId: paymentId,
                            debug: 'error'
                        }
                    )
            },
            onIncompletePaymentFound: function(paymentDTO)
            {
                paymentId = paymentDTO.identifier
                console.log('onIncompletePaymentFound', paymentId)
                $.post('/payment/complete',
                        {
                            paymentId: paymentId,
                            txid: paymentDTO.transaction.txid
                        }
                    )
             }
        };
        Pi.createPayment(paymentData, paymentCallbacks);
    }
</script>

2. 将此代码添加到 app.py 文件中

这样就设置好了我之前提到的 Flask 路由。这些只是 Pi 的路由。你需要设置任何特定于应用程序的路由。对我来说,这些路由是get_quote和back 。或者,你也可以直接下载整个代码库。

Python
@app.route('/payment/approve', methods=['POST'])
def approve():
    # Build the header for user authentication
    accessToken = request.form.get('accessToken')
    userheader = {
        'Authorization': f"Bearer {accessToken}"
    }
    paymentId = request.form.get('paymentId')
    approveurl = f"https://api.minepi.com/v2/payments/{paymentId}/approve"
    response = requests.post(approveurl, headers=header)
    userurl = "https://api.minepi.com/v2/me"
    userresponse = requests.get(userurl, headers=userheader)
    userjson = json.loads(userresponse.text)
    return(response.text)

@app.route('/payment/complete', methods=['POST'])
def complete():   
    # Build the header for user authentication
    accessToken = request.form.get('accessToken')
    userheader = {
        'Authorization': f"Bearer {accessToken}"
    }
    paymentId = request.form.get('paymentId')
    txid = request.form.get('txid')
    userurl = "https://api.minepi.com/v2/me"
    userresponse = requests.get(userurl, headers=userheader)
    data = {'txid': txid}
    approveurl = f"https://api.minepi.com/v2/payments/{paymentId}/complete"
    response = requests.post(approveurl, headers=header, data=data)
    return(response.text)

@app.route('/payment/cancel', methods=['POST'])
def cancel():    
    paymentId = request.form.get('paymentId')
    approveurl = f"https://api.minepi.com/v2/payments/{paymentId}/cancel"
    response = requests.post(approveurl, headers=header)
    return(response.text)

@app.route('/payment/error', methods=['POST'])
def error():    
    paymentId = request.form.get('paymentId')
    approveurl = f"https://api.minepi.com/v2/payments/{paymentId}/cancel"
    response = requests.post(approveurl, headers=header)
    return(response.text)

@app.route('/me', methods=['POST'])
def getme():
    userurl = "https://api.minepi.com/v2/me"
    response = requests.post(userurl, headers=header)
    return(response.text)

这些新路线具有以下功能:

  • /payment/approve连接到 Pi SDK,并启动整个支付/审批流程。当用户点击“支付”按钮时,JavaScript 的 createPayment 函数会触发此请求。此时,Pi 平台上会发生一系列复杂的操作。如果支付获得批准,SDK 将调用完整的路由。
  • /payment/complete获取交易 ID(唯一的交易字符串),并触发 me 路由
  • /payment/cancel和error这两个路由的名称正如其名,但我比较懒,所以它们都向 SDK 的取消 URL 发送请求。

3. 确保它们连接起来

要将你的应用连接到 Pi SDK,你只需要让某个应用触发 createPayment 事件即可。对我来说,就是“支付”按钮:

 Javascript
<a href="#" id="resetBtn" class="btn btn-primary mt-3" OnClick='javascript:createPayment();'>Pay</a>

当有人点击“支付”按钮时,会调用createPayment 函数,该函数随后会调用 Flask 路由 /payments/approve。然后,神奇的事情就发生了。

目前耗时:< 4 小时,扣除愚蠢时间

目前,我的应用程序已经可以正常运行。它会显示一些侮辱性的内容,向我收取 Pi 的费用,以及完成其他各种操作。

那又花了大约4个小时,外加一些额外时间:

  1. 括号不匹配,因为我就是那个开发者
  2. 我家猫和狗之间爆发了一场旷日持久的消耗战,猫咪趴在咖啡桌上,尾巴在阿尔弗雷德面前晃来晃去,阿尔弗雷德见状就疯狂地想抓住它的尾巴。
  3. 我完全没搞懂SDK的真正作用。如果我稍微考虑一下,就能更快地完成搭建和运行了。

我会帮你省去这些麻烦。请阅读下一节,了解具体操作方法:

这一切究竟在做什么

到这里,你可能已经眼花缭乱了。这需要大量的复制粘贴操作,或者(希望如此)查看代码库。但你却很难真正理解它是如何运作的。以下是分步指南:

  1. 首次访问。页面打开,SDK 加载Pi.init。
  2. Pi.authenticate由应用程序调用,用于检查我们是否已通过身份验证。如果未通过身份验证,Pi 会显示安全警告并请求用户允许继续操作。
  3. 假设一切顺利,用户也授予了权限,Pi.authenticate会获取user.username并将其写入页面,以营造个性化的体验。
  4. 用户点击“给我一句侮辱”几次。每次点击都会调用/get_quote路由。
  5. 如果用户点击超过三次,应用程序会弹出支付请求的模态框(是的,这很可笑,而且很容易用弹出窗口拦截器绕过——这是为了科学,好吗?)。
  6. 用户对侮辱的质量非常满意,点击“付款”按钮确认付款。
  7. 当他们这样做时,模态框会调用createPayment 函数。
  8. createPayment调用onReadyForServerApproval ,这会在 Flask 应用中触发/payment/approve路由,并将paymentId和accessToken发送给 Flask。
  9. /payment/approve路由会向 API 发送包含支付 ID 和访问令牌的请求。
  10. 作为回应,API(理想情况下)会返回“好的,一切正常”,此时SDK会调用onReadyForServerCompletion函数。
  11. 这会调用 Flask 的/payment/complete路由,并向其传递paymentId 最重要的txid (交易 ID)。
  12. /payment/complete Flask路由处理付款

关于未完成付款

这个小函数差点把我逼疯。它功能很强大,可以检查未完成的交易,并允许你调用其他函数。我一开始没搞懂。 

有好几次,我把系统搞坏了,导致交易提交了但没完成。这简直就是一场灾难,我尝试调试,尝试再次提交付款,失败了,然后再次尝试调试……真是惨不忍睹。

就我的目的而言,我在 onIncompletePaymentFound 事件中调用了 /payment/complete。现在,每当有未完成的交易时,用户下次加载应用时,交易就会完成,并允许他们继续发表侮辱性言论。 

这些都是小额交易,而且只是个测试,所以我宁愿完成交易继续测试。另外,我也想确保全球经济中不断有侮辱性的言论涌入。

在生产环境中,你可能需要取消交易或执行更高级的操作。

使用身份验证:附注

提供的代码已经实现了所有这些功能。这里只是做个解释。

光开发应用还不够。不!我还想在几个地方显示用户名。为此,我必须使用身份验证。通常,我一听到“身份验证”,就会想到 OAuth 这个噩梦。不过,这次 SDK 已经完成了大部分工作。 

更改身份验证 Javascript 并添加 <span>

我把用于验证用户身份的代码块改成了这样:

 Javascript
// Authenticate the user, and get permission to request payments from them (added 'username' to provide username to API):
const scopes = ['payments','username'];
var accessToken
var username


// Read more about this callback in the SDK reference:
function onIncompletePaymentFound(payment) { 
    paymentId = payment.identifier
    txid = payment.transaction.txid
    $.post('/payment/complete',
            {
                paymentId: paymentId,
                txid: txid,
                debug: 'cancel'
            }
        )
};

Pi.authenticate(scopes, onIncompletePaymentFound).then(function(auth) {
  accessToken = auth.accessToken
  username = auth.user.username
  $('#username').text(username); // writes username to the page
}).catch(function(error) {
  console.error(error);
});

accessToken = auth.accessToken
username = auth.user.username
$('#username').text(username); // writes username to the page
}).catch(function(error) {
  console.error(error);
});

你可以自己对比,不过复制粘贴也可以。以下是修改内容:

  • 添加用户名作用域并创建用户名变量后,应用程序可以从 API 获取用户的帐户名,然后在页面上使用它。
  • 将 accessToken 和用户名添加到 Pi.authenticate 中,即可将信息传递给页面并在此处显示:
伊恩编写了一个区块链应用程序

我还添加了一个id 为#username 的<span> 标签。用户的账号名称会显示在这里。

将 /me 添加到我的 Flask 路由

我在 app.py 文件中添加了“/me”路由: 

Python
@app.route('/me', methods=['POST'])
def getme():
    userurl = "https://api.minepi.com/v2/me"
    response = requests.post(userurl, headers=header)
    return(response.text)

这会向 API 发出调用并检索用户的帐户名。

我还向`/payments/complete`路由添加了几行代码。不过因为我比较懒,所以已经把这些代码包含在上面的复制粘贴代码块里了。如果你下载整个应用仓库,一切就都搞定了。

完毕!

搞定了!我现在有了一个完整的应用程序。它提供了一些侮辱性话语,可以进行个性化设置,甚至可以自动复制预先写好的消息(包括侮辱性话语),方便通过电子邮件、社交媒体或其他任何方式发送:

伊恩编写了一个区块链应用程序

伊恩式调试

我经常使用 console.log。如果你也像我一样是新手,可以点击这里了解更多信息。

任务完成

我升级了吗?我不确定。但我从未想过自己能把区块链技术融入到我开发的任何项目中。我之前没意识到它竟然如此简单,只需要添加一些 JavaScript 代码,或者可以用我的老朋友 Python 来完成这项工作。

所以是平局:区块链 1 分,伊恩 1 分

猫和狗因为表现(勉强算)好而都得到了奖励,所以它们各得 2 分。

说明:本公告转载自 Pi Network 项目方官网的Blog栏目。原文是英文版,转载前使用Chrome浏览器(谷歌浏览器)自带的翻译工具全文翻译后发布分享在OK派导航网。原文链接:https://minepi.com/blog/build-blockchain-app/ (注:访问Pi官网页面需先打开梯子加速)。

免责声明:本站内容仅为Web3行业相关资讯分享,不构成任何投资建议。加密/数字资产风险极高,可能导致本金完全损失,用户应独立判断并自行承担全部风险和责任。本站不对信息的准确性及第三方链接内容真实性负责。访问本站即视为接受此声明。
© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享