概述
本文将介绍不同的工具和技术,你可以用来帮助在Flow区块链上构建。由于文章的重点是工具,我们假设你已经对Cadence有了基本了解。如果没有,欢迎你参加Cadence的教程https://developers.flow.com/cadence/tutorial/01-first-steps
我们将涉及很多主题和技术,所以我们必须假设你对这些技术有基本的了解:
- Cadence编程语言
- 公钥私钥
- 流动区块链
但是,如果你需要澄清某些方面的问题,也不用担心;我们将提供方便的链接,你可以在我们的过程中了解更多信息。
本指南的目的是让你熟悉Flow的流程,也就是说,从开始在本地开发一个应用程序到在Mainnet上进行生产部署,你需要哪些工具,采取哪些步骤。
⏱️ 阅读时间约为30分钟,所以现在就去煮咖啡,然后跟着一起去。
1分钟的Flow介绍
我将通过开发人员的镜头迅速向你介绍Flow的最基本情况,如果你知道Flow是如何工作的,请随意跳过这部分。
Flow是一个去中心化的区块链,通过拥有多个单一用途的节点(执行节点、收集节点、访问节点等)来引入一种新的扩展方法。访问节点是我们感兴趣的,因为它给我们提供了一种通过连接其API来访问Flow网络的方法,但不用担心;我们有缓解与该节点通信的库。
与访问节点进行通信,我们可以提交新的交易,执行脚本,并获得区块链信息,如区块、交易等。你可以在这里阅读更多关于Flow的工作原理,但这些知识在本指南中是可选的。通过发送包含调用任何合约的Cadence代码的交易,以及突变Flow区块链,就可以与Flow互动。把它们看作是 "写操作"。如果你只需要查询或 "读取 "区块链,你可以使用脚本,它同样可以包含任何Cadence代码,但不会以任何方式改变Flow网络,而是返回我们感兴趣的信息,如调用合约函数。
Flow还介绍了其名为Cadence的编程语言。Cadence是区块链的优秀语言,因为它是面向资源的,这保证了资源(特定类型)一次只能存在于一个地方,不能被复制,也不能被意外丢失或删除。在这里查看完整的Cadence语言参考资料,但我们以后写合约时将会涉及一些基础知识。
Flow的另一个独特的属性使其非常出色,是其独特的账户设计模型。帐户不只是用从私钥派生出来的地址来表示(例如,像在以太坊上),而是生活在Flow网络上的实际实体,这意味着,你可以通过调用一个函数在网络上创建一个新的帐户,并为其分配任何密钥,你甚至可以完全改变密钥以及删除它们,然后该帐户成为只读。
与其他网络相比,账户给了你更多授权访问的权力。账户有其存储空间,你可以非常便宜地存储任何数据(目前1MB为0.01的Flow)。你可以在这里阅读更多关于Flow的关键组成部分。
Flow甚至引入了一种无钱包入职的方式,这是另一篇文章的主题。
目前有多个Flow网络可用于不同的目的。你可以通过访问节点的API(目前是gRPC和HTTP APIs,但不用担心这些,因为SDK支持它们)来访问这些网络。这些API在不同的地址上可用:
- Emulator APIs [localhost:3569](<http://localhost:3569>) - locally run Flow network using the emulator tool
- Testnet APIs [access.devnet.nodes.onflow.org:9000](<http://access.devnet.nodes.onflow.org:9000>) - testnet is used for testing your application, similar to how staging is in web2 world,****
- Mainnet APIs [access.mainnet.nodes.onflow.org:9000](<http://access.mainnet.nodes.onflow.org:9000>) - mainnet is the production Flow network****
流动工具和技术
Building on Flow可以使用我们提供的不同技术,所以我们将看看一些最常见的技术,但请记住,还有更多的技术可以让你自由选择。
JS FCL
在编写javascript应用程序时,我们可以使用JS FCL SDK,简单地说就是Flow的javascript SDK。它允许我们通过发送交易、执行脚本、读取区块和事件等方式与Flow网络互动。尽管如此,由于大多数应用程序想要发送交易以改变Flow区块链数据,他们必须以某种方式签署这些交易。如果你来自以太坊,你知道这个问题是通过在Flow上使用不同的钱包如Metamask来解决的,然而,我们发现了一个更好的解决方案,它已经为你内置于FCL SDK中。SDK知道如何连接到可用的钱包供应商,并要求用户用你在演示中早些时候看到的模式来确认交易的签署。这是通过钱包发现协议实现的,你可以在这里阅读更多关于它的内容,但现在,你不必太担心;把它看作是Flow的OAuth。
当然,为了让用户登录,他们需要有一个现有的钱包与所选择的供应商。正如下面所解释的,我们在开发过程中用dev钱包模拟了这个钱包提供商。你可以在这里找到完整的FCL参考资料。总之,如果你正在为你的DApp构建一个前端,你需要FCL来与钱包和Flow互动。下面是FCL SDK与所有其他工具(如开发钱包和模拟器)进行通信的快速示意图。
CLI
在使用Flow时,Flow CLI是一把瑞士军刀。它提供了发送交易、执行脚本和获取区块的命令,但也包括其他工具,如Flow仿真器、开发钱包和Flowser。它提供的开发工具可以观察你的合约,并在开发过程中保持它们的自动更新。它还知道如何解决其他合约的导入问题,以及你在开发过程中需要的更多很酷的功能。
下面是帮助屏幕的偷窥:
流动.json
flow.json文件包含你项目的配置。在那里,我们定义了我们将部署的合同,我们在网络上创建的账户,以及我们可以访问的不同网络。Flow.json被其他工具和库(如FCL)所消费,是消费者之间的粘合剂。你可以在这里阅读更多关于flow.json的信息。
flow.json文件的例子:
流程 仿真器
Flow模拟器是一个在你的本地机器上运行简单版本的Flow网络的工具,可用于开发。它在实时的Flow主网上暴露了相同的Access Node APIs。你可以通过Flow CLI运行flow emulator命令来快速启动Flow模拟器。仿真器提供一个输出,你可以看到它执行的交易和不同的日志。
发展钱包
Dev钱包是一个在本地模拟FCL兼容的钱包的工具。它实现了FCL需要的特定API,以便与它进行通信并签署交易。开发钱包会自动生成一个你可以在开发过程中使用的钱包。现在,你可以把它看作是一个黑匣子工具,使你能够像用户在生产部署中那样签署任何交易。当然,在生产中,开发钱包将被任何生产钱包供应商取代,如Blocto或Lilico钱包。
流浪者
Flowser是一个优秀的GUI工具,用于可视化Flow仿真器的区块链。它使开发更加直接,因为它允许你检查网络上正在发生的事情,你可以把它看作是模拟器的图形界面,但它也包含了更多的功能,如账户存储检查。你可以从Flowser运行模拟器和开发钱包。下载它并在他们的网站上了解更多信息 https://flowser.dev/
VSCode Cadence扩展
我们要介绍的最后一个工具是Visual Studio Code Cadence扩展,它是最适合开发Cadence的IDE,因为该扩展支持语法高亮、自动完成、代码检查等。你可以在这里获得该IDE;该扩展在市场上有售。
其他工具
还有许多由社区建立的工具和库可以在你的开发过程中帮助你,而这些工具和库没有我们涵盖的那么重要。在我们的开发者门户网站上了解更多关于它们的信息。
设置一个Cadence项目
我们将使用Flow CLI设置命令从头开始。
This will create a new empty project folder named helloWorld and include a cadence folder as well as flow.json
Your project comes with some standard folders which have a special purpose:
- /cadence inside here is where your Cadence smart contracts code lives
- flow.json configuration file for your project, you can think of it as package.json, but you don't need to worry, flow dev command will configure it for you
Inside cadence folder you will find:
- /contracts location for Cadence contracts go in this folder
- /scripts location for Cadence scripts goes here
- /transactions location for Cadence transactions goes in this folder
- /tests all the integration tests for your dapp and Cadence tests go into this folder
You can read more about your project in the README.md that was created in the project folder, but we will cover everything here as well.
Now start up your development environment by running flowser, clicking on create a new project and choosing a name and the folder we just created, or by manually running flow emulator and flow dev-wallet in the project directory. We suggest going with the first option as it’s easier to manage.
This is what you should see:
As you can see, there are already some accounts created. The first is a service account, like an "admin" account on the Flow network, and other accounts containing pre-deployed contracts. No need to stress about it now. We can ignore it for now.
Then in your project directory, start the flow dev command, which will watch for any changes in the contracts folder and make sure they are deployed for you on the network so that you can focus your attention on the coding. We will do this by opening a project in VSCode and running flow dev in the terminal inside VSCode. Make sure you have installed the Cadence extension.
Your IDE should now look like this:
Writing your first Cadence contract
We are going to start by adding a new contract in the cadence/contracts folder named Person.cdc and with the content.
Click save, and you are done.
🎉 Congratulations, you just deployed your first contract to the Flow network.
What happened is the flow dev command you ran detected new contracts in the contracts folder and automatically deployed a contract on the emulator you are running.
Let’s make the Person contract a bit more interesting, so we can then write a script to query it and a transaction to change some data.
Add this to the contract:
What this will do is add a variable on the contract called name where we will be able to assign a value in the init method, which is the contract constructor.
💡 Hardcoding the values in the constructor is suggested during development. After you finish the contract, you should change the constructor to accept values as function parameters.
Click save again, and the contract will be automatically updated.
Scripts
Do you remember how we mentioned Flow scripts are Cadence programs that can read something from the Flow blockchain and return data but can not change things? Well, scripts will make help us now to query the contract and call sayHello() method.
Let’s write a script called sayHello.cdc and put it inside the scripts folder /cadence/scripts . Add this content in it:
This imports the deployed contract we just created by its name. Then we can call the function defined on the contract called sayHello(), which returns a String, so we return that as the script return value.
We can now test this out by executing the script using the flow CLI:
Awesome, it works! You just queried some data from the Flow blockchain. Give yourself a pat on the shoulder, and let’s continue by forever changing some data on Flow blockchain by using transactions.
Transactions
First of all, let me say we could call the same function using a transaction, but that wouldn’t accomplish much, so we want to call a function that changes something. Let’s add such a function to the Person contract. Let’s add a friendship resource and a function that creates that resource. If you want to learn about resources please check the Cadence resources documentation. Add this to the Person contract:
This way we add a new function called makeFriends() that returns a Friendship resource. Now let’s call this function in a transaction.
Add a new transaction file to the cadence/transactions folder called makeFriends.cdcAnd put this code in it:
So we defined a transaction, and if you want to read more about transactions you can here but what this will do is first import Person contract we defined and automatically deployed, then it will call the Person.makeFriends() method, which will return a resource that will directly get saved into account storage. So let’s make some friends and send a transaction using Flow CLI.
So we can see the transaction was SEALED which means it was included on the Flow blockchain. The execution was also successful otherwise we would see an error.Can we check if the resource was really saved in an account? and which account was that in the first place? So we can see the payer is f8d6e0586b0a20c7 which is the account that was used, by default, if we don’t explicitly define an account, this service account will be used. Think of it as a default admin account we always get on the emulator.
Let’s look into Flowser, find the above account, and check the storage. We can see there indeed is a “friendship” resource in the storage section.
Congrats, you change Flow blockchain forever, well until you restart your emulator. You see when the emulator is restarted the data clears. If you want to keep the emulator blockchain data between restarts you should add a --persist flag when running the emulator like so: flow emulator --persist
But let's deploy our project to the testnet and then mainnet and change the Flow blockchain forever.
Moving from Emulator to Testnet
Deploying our just-made project to testnet is not hard, but it requires from us to first create an account on testnet we can use, to deploy the contracts to.
Creating testnet account
Creating a testnet account is easy using the Flow CLI run the following command inside the project directory:
Enter a new account name and choose testnet as the network. After, you should see the above output. Please note the address in your case is gonna be different.
So we see an account was created and saved into flow.json, but its key was added to a separate file that we should never share with anyone.
Now we need to define a deployment we want to use on testnet. In our case is gonna be simple since we only have one contract, and we need that contract to get deployed on the newly created account. We run another CLI command:
So we choose testnet as the network for deployment, the name of the account we just created (alice in our case), the “Person” contract we want to deploy, and that’s it.
As it already says we can now deploy our project by running project deploy command, so let’s do that:
It says we deployed one contract on the account Alice. Congrats, we’ve just deployed a contract on testnet 🎉
Updating Contracts
What if we want to change our deployed contracts, lets say we change the accessibility of the variable name from public pub to private priv, like so:
We can easily update the contracts by adding an --updae flag to the above command like so:
We can see the “Person” contract was updated.
⚠️ Please be very careful when updating contracts, as you are limited in changes you can make to already deployed contracts on testnet, which is described in the Cadence documentation. That’s why it’s better to first iterate and develop the contract using an emulator, where we don’t have these kinds of enforcements.
Since we’ve now created a contract on testnet, we can try to interact with it using the same script and transactions as before. Good news, the command stays the same and you bearly need to change anything.
Execute the script by adding the --network testnet flag like so:
And a transaction by adding the --network testnet flag and also a signer flag set to the account we created --signer alice
We need to add the --signer flag to say which account will sign the transaction and pay for it, it doesn’t need to be the same account as the one we deployed the contract to, but it needs to be an existing testnet account, and since we created one for contract we may as well reuse it for this purpose.
🎊 Congratulations. you’ve just interacted with testnet!
Moving from Testnet to Mainnet
After you’ve successfully established a testnet environment and further test it that made you decide you are ready to go to mainnet, you can repeat a very similar process for mainnet.
❗🚨 Before we do so, couple of very important things to note:
- Creating an account on the mainnet is a simple procedure not different from the one seen for the testnet, but the account keys should be kept safe at all times. Anyone obtaining access to those keys can change the contract and exploit your application. We even suggest protecting your account by using Amazon or Google KMS for signing.
- Deploying to mainnet should be the very last action in the development process, meaning you should make sure your application works well, it’s extensively tested, and doesn’t have bugs.
Going from emulator to mainnet is like playing with clay, at first it’s very soft and can easily be changed and molded and the more you move towards mainnet more permanent it becomes. Changing the mainnet dapp is very hard and should be avoided as much as possible.
After all the disclaimers let’s create a mainnet account using the CLI:
Add a deployment:
And deploy to the mainnet using the CLI command:
You are done. You have successfully deployed your application to mainnet.
Congrats 🎊 🎉
How can we check the deployment? we can use flowscan and enter the address of the account used in the deployment (the one we just created before), like so:
https://flowscan.org/account/0xbd9b4d46cb027518
And we can see it includes our contract https://flowscan.org/contract/A.bd9b4d46cb027518.Person