Hyperledger Fabric v1.4(LTS) 系列(5.6.2):Developing Applications- Application design elements-Chaincode namespace
Chaincode namespace
Audience: Architects, application and smart contract developers,
administrators
A chaincode namespace allows it to keep its world state separate from other chaincodes. Specifically, smart contracts in the same chaincode share direct access to the same world state, whereas smart contracts in different chaincodes cannot directly access each other’s world state. If a smart contract needs to access another chaincode world state, it can do this by performing a chaincode-to-chaincode invocation. Finally, a blockchain can contain transactions which relate to different world states.
链码的命名空间用于把每个链码的全局状态和其他的区隔开。同一个链码中的智能合约共享同一个全局状态,但不同链码中的合约不可以。如果要跨链码访问全局状态,可以通过链码到链码的调用。最终区块链可以包含关联到不同全局状态的交易。
In this topic, we’re going to cover:
- The importance of namespaces
- What is a chaincode namespace
- Channels and namespaces
- How to use chaincode namespaces
- How to access world states across smart contracts
- Design considerations for chaincode namespaces
Motivation
A namespace is a common concept. We understand that Park Street, New York and Park Street, Seattle are different streets even though they have the same name. The city forms a namespace for Park Street, simultaneously providing freedom and clarity.
It’s the same in a computer system. Namespaces allow different users to program and operate different parts of a shared system, without getting in each other’s way. Many programming languages have namespaces so that programs can freely assign unique identifiers, such as variable names, without worrying about other programs doing the same. We’ll see that Hyperledger Fabric uses namespaces to help smart contracts keep their ledger world state separate from other smart contracts.
Scenario
Let’s examine how the ledger world state organizes facts about business objects
that are important to the organizations in a channel using the diagram below.
Whether these objects are commercial papers, bonds, or vehicle registrations,
and wherever they are in their lifecycle, they are maintained as states within
the ledger world state database. A smart contract manages these business objects
by interacting with the ledger (world state and blockchain), and in most cases
this will involve it querying or updating the ledger world state.
账本以全局状态组织业务对象的数据并提供查询和更新。
It’s vitally important to understand that the ledger world state is partitioned
according to the chaincode of the smart contract that accesses it, and this
partitioning, or namespacing is an important design consideration for
architects, administrators and programmers.
账本的全局状态按照访问账本的智能合约所属的链码分区。
[外链图片转存失败(img-DjBMsh2U-1564407200733)(https://hyperledger-fabric.readthedocs.io/en/release-1.4/_images/develop.diagram.50.png)]
The ledger world state is separated into different namespaces according to the chaincode that accesses it. Within a given channel, smart contracts in the same chaincode share the same world state, and smart contracts in different chaincodes cannot directly access each other’s world state. Likewise, a blockchain can contain transactions that relate to different chaincode world states.
一个给定的通道内,同一个链码内的智能合约共享同一份全局状态,不同链码的合约则不能直接访问。
In our example, we can see four smart contracts defined in two different chaincodes, each of which is in their own chaincode container. The euroPaper
and yenPaper
smart contracts are defined in the papers
chaincode. The situation is similar for the euroBond
and yenBond
smart contracts – they are defined in the bonds
chaincode. This design helps application programmers understand whether they are working with commercial papers or bonds priced in Euros or Yen, and because the rules for each financial product don’t really change for different currencies, it makes sense to manage their deployment in the same chaincode.
例子中papers链码里有euroPaper和yenPaper合约,bonds链码里有euroBond和yenBond合约。
The diagram also shows the consequences of this deployment choice. The database management system (DBMS) creates different world state databases for the papers
and bonds
chaincodes and the smart contracts contained within them. World state A
and world state B
are each held within distinct databases; the data are isolated from each other such that a single world state query (for example) cannot access both world states. The world state is said to be namespaced according to its chaincode.
See how world state A
contains two lists of commercial papers paperListEuro
and paperListYen
. The states PAP11
and PAP21
are instances of each paper managed by the euroPaper
and yenPaper
smart contracts respectively. Because they share the same chaincode namespace, their keys (PAPxyz
) must be unique within the namespace of the papers
chaincode, a little like a street name is unique within a town. Notice how it would be possible to write a smart contract in the papers
chaincode that performed an aggregate calculation over all the commercial papers – whether priced in Euros or Yen – because they share the same namespace. The situation is similar for bonds – they are held within world state B
which maps to a separate bonds
database, and their keys must be unique.
账本里创建了World state A和World state B。World state A包含了叫paperListEuro和paperListYen的两个列表。状态PAP11和PAP21是euroPaer和yenPaper票据的实例。这里可以有一个对所有商票的汇聚计算因为他们在一个命名空间里。
Just as importantly, namespaces mean that euroPaper
and yenPaper
cannot directly access world state B
, and that euroBond
and yenBond
cannot directly access world state A
. This isolation is helpful, as commercial papers and bonds are very distinct financial instruments; they have different attributes and are subject to different rules. It also means that papers
and bonds
could have the same keys, because they are in different namespaces. This is helpful; it provides a significant degree of freedom for naming. Use this freedom to name different business objects meaningfully.
world state A/B不能直接互访,是隔离的,在实际商业活动中也是这样的。
Most importantly, we can see that a blockchain is associated with the peer operating in a particular channel, and that it contains transactions that affect both world state A
and world state B
. That’s because the blockchain is the most fundamental data structure contained in a peer. The set of world states can always be recreated from this blockchain, because they are the cumulative results of the blockchain’s transactions. A world state helps simplify smart contracts and improve their efficiency, as they usually only require the current value of a state. Keeping world states separate via namespaces helps smart contracts isolate their logic from other smart contracts, rather than having to worry about transactions that correspond to different world states. For example, a bonds
contract does not need to worry about paper
transactions, because it cannot see their resultant world state.
链在更底层,是和一组特定通道内的节点关联,包含了world state A/B的交易。
It’s also worth noticing that the peer, chaincode containers and DBMS all are logically different processes. The peer and all its chaincode containers are always in physically separate operating system processes, but the DBMS can be configured to be embedded or separate, depending on its type. For LevelDB, the DBMS is wholly contained within the peer, but for CouchDB, it is a separate operating system process.
节点、链码容器和DBMS逻辑分离,节点和链码容器往往也是物理分离的,DBMS可以嵌入或分离。
It’s important to remember that namespace choices in this example are the result of a business requirement to share commercial papers in different currencies but isolate them separate from bonds. Think about how the namespace structure would be modified to meet a business requirement to keep every financial asset class separate, or share all commercial papers and bonds?
技术设计是服务于商业需要的。
Channels
If a peer is joined to multiple channels, then a new blockchain is created and managed for each channel. Moreover, every time a chaincode is instantiated in a new channel, a new world state database is created for it. It means that the channel also forms a kind of namespace alongside that of the chaincode for the world state.
一个节点可以加入多个通道,每加入一个则就会创建一个区块链服务于该通道。每当链码在一个新的通道被实例化,一套新的全局状态数据库就被为它创建。这也意味着,通道也和链码组成了一种命名空间。
However, the same peer and chaincode container processes can be simultaneously joined to multiple channels – unlike blockchains, and world state databases, these processes do not increase with the number of channels joined.
相同的节点和链码容器进程可以同时加入到多个通道,这与区块链和全局状态数据库不同,这些进程不会随着加入的通道的数量而增加(而链和全局状态库则是每加入一个新通道就新建一套)。
For example, if the papers
and bonds
chaincodes were instantiated on a new channel, there would a totally separate blockchain created, and two new world state databases created. However, the peer and chaincode containers would not increase; each would just be connected to multiple channels.
例如,如果“票据”和“债券”链码在一个新的通道上被实例化,将创建一个完全独立的区块链,并创建两个新的全局状态库。但是,节点和链码容器不会增加;每个容器都会连接到多个通道。
Usage
Let’s use our commercial paper example to show how an application uses a smart contract with namespaces. It’s worth noting that an application communicates with the peer, and the peer routes the request to the appropriate chaincode container which then accesses the DBMS. This routing is done by the peer core component shown in the diagram.
用商票场景演示应用如何通过智能合约和命名空间交互。应用和节点通信,节点路由请求到对应的链码容器,链码访问DBMS。路由的事情由上图中的节点核心组件完成。
Here’s the code for an application that uses both commercial papers and bonds, priced in Euros and Yen. The code is fairly self-explanatory:
const euroPaper = network.getContract(papers, euroPaper);
paper1 = euroPaper.submit(issue, PAP11);
const yenPaper = network.getContract(papers, yenPaper);
paper2 = yenPaper.submit(redeem, PAP21);
const euroBond = network.getContract(bonds, euroBond);
bond1 = euroBond.submit(buy, BON31);
const yenBond = network.getContract(bonds, yenBond);
bond2 = yenBond.submit(sell, BON41);
See how the application:
结合上图看
- Accesses the
euroPaper
andyenPaper
contracts using thegetContract()
API specifying thepapers
chaincode. See interaction points 1a and 2a.
1a 2a是链码papers容器中euroPaper和yenPaper的交互点。
- Accesses the
euroBond
andyenBond
contracts using thegetContract()
API specifying thebonds
chaincode. See interaction points 3a and 4a.
3a 4a是链码bonds容器中euroBond和yenBond的交互点。
- Submits an
issue
transaction to the network for commercial paperPAP11
using theeuroPaper
contract. See interaction point 1a. This results in the creation of a commercial paper represented by statePAP11
inworld state A
; interaction point 1b. This operation is captured as a transaction in the blockchain at interaction point 1c.
通过合约euroPaper向商票PAP11提交issue交易,看交互点1a。创建商票的结果以world state A中的PAP11呈现,即1b。结果在链上以1c保存。
-
Submits a
redeem
transaction to the network for commercial paperPAP21
using theyenPaper
contract. See interaction point 2a. This results in the creation of a commercial paper represented by statePAP21
inworld state A
; interaction point 2b. This operation is captured as a transaction in the blockchain at interaction point 2c. -
同上,通过合约yenPaper向网络提交PAP21的redeem交易,见2a。结果在world state A中以状态PAP21呈现,即2b。操作在链上以2c保存。
-
Submits a
buy
transaction to the network for bondBON31
using theeuroBond
contract. See interaction point 3a. This results in the creation of a bond represented by stateBON31
inworld state B
; interaction point 3b. This operation is captured as a transaction in the blockchain at interaction point 3c. -
Submits a
sell
transaction to the network for bondBON41
using theyenBond
contract. See interaction point 4a. This results in the creation of a bond represented by stateBON41
inworld state B
; interaction point 4b. This operation is captured as a transaction in the blockchain at interaction point 4c.
See how smart contracts interact with the world state:
智能合约如何和全局状态交互
euroPaper
andyenPaper
contracts can directly accessworld state A
, but cannot directly accessworld state B
.World state A
is physically held in thepapers
database in the database management system (DBMS) corresponding to thepapers
chaincode.
euroPaper和yenPaper可以直接访问world state A,但不能直接访问属于bonds的world state B.World state A在对应papers链码的DBMS的papers库中。
euroBond
andyenBond
contracts can directly accessworld state B
, but cannot directly accessworld state A
.World state B
is physically held in thebonds
database in the database management system (DBMS) corresponding to thebonds
chaincode.
See how the blockchain captures transactions for all world states:
- Interactions 1c and 2c correspond to transactions create and update commercial papers
PAP11
andPAP21
respectively. These are both contained withinworld state A
.
1c和2c对应商票PAP11和21的创建与更新,二者都包含在world state A中。
-
Interactions 3c and 4c correspond to transactions both update bonds
BON31
andBON41
. These are both contained withinworld state B
. -
If
world state A
orworld state B
were destroyed for any reason, they could be recreated by replaying all the transactions in the blockchain.
如果world state A或B丢失了,可以通过重放链中的交易重建。
Cross chaincode access
As we saw in our example scenario, euroPaper
and yenPaper
annot directly access world state B
. That’s because we have designed our chaincodes and smart contracts so that these chaincodes and world states are kept separately from each other. However, let’s imagine that euroPaper
needs to access world state B
.
如上图,票据不能直接访问债券的全局状态world state B。但是如果需要访问呢?
Why might this happen? Imagine that when a commercial paper was issued, the smart contract wanted to price the paper according to the current return on bonds with a similar maturity date. In this case it will be necessary for the euroPaper
contract to be able to query the price of bonds in world state B
. Look at the following diagram to see how we might structure this interaction.
当商票发行时,智能合约需要根据具有类似到期日的债券收益率来定价。euroPaper合约就需要查询world state B中债券的价格。
[外链图片转存失败(img-2dnrn9Wb-1564811578273)(https://hyperledger-fabric.readthedocs.io/en/release-1.4/_images/develop.diagram.51.png)]
How chaincodes and smart contracts can indirectly access another world state – via its chaincode.
Notice how:
-
the application submits an
issue
transaction in theeuroPaper
smart contract to issuePAP11
. See interaction 1a. -
the
issue
transaction in theeuroPaper
smart contract calls thequery
transaction in theeuroBond
smart contract. See interaction point 1b. -
the
query
ineuroBond
can retrieve information fromworld state B
. See interaction point 1c. -
when control returns to the
issue
transaction, it can use the information in the response to price the paper and updateworld state A
with information. See interaction point 1d. -
the flow of control for issuing commercial paper priced in Yen is the same. See interaction points 2a, 2b, 2c and 2d.
应用向euroPaper合约提交issue交易,见1a。euroPaper中的issue交易调用euroBond的query交易,见1b。euroBand里query从world state B中查询结果,见1c。控制权回到issue交易,使用返回的价格信息更新world state A,见1d。
Control is passed between chaincode using the invokeChaincode()
API. This API passes control from one chaincode to another chaincode.
控制权通过invodeChaincode API在链码之间传递。
Although we have only discussed query transactions in the example, it is possible to invoke a smart contract which will update the called chaincode’s world state. See the considerations below.
Considerations
-
In general, each chaincode will have a single smart contract in it.
-
Multiple smart contracts should only be deployed in the same chaincode if they are very closely related. Usually, this is only necessary if they share the same world state.
-
Chaincode namespaces provide isolation between different world states. In general it makes sense to isolate unrelated data from each other. Note that you cannot choose the chaincode namespace; it is assigned by Hyperledger Fabric, and maps directly to the name of the chaincode.
-
For chaincode to chaincode interactions using the
invokeChaincode()
API, both chaincodes must be installed on the same peer.-
For interactions that only require the called chaincode’s world state to be queried, the invocation can be in a different channel to the caller’s chaincode.
-
For interactions that require the called chaincode’s world state to be updated, the invocation must be in the same channel as the caller’s chaincode.
-
一般情况,每个链码只有一个智能合约。
多合约强相关或需要共享world state时才部署在一个链码里。
链码命名空间提供了world state的隔离,命名空间不能选择,是Fabric按照链码名称分配的。
链码之间通过invodeChaincode交互,交互的链码必须安装在相同节点。如果只查询链码全局状态,调用可以跨通道。如果要更新,则必须是同一个通道的链码