免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

如何利用HyperledgerFabric的SDK來開發(fā)RESTAPI服務(wù)器

這篇文章主要為大家展示了“如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習一下“如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器”這篇文章吧。

目前創(chuàng)新互聯(lián)已為成百上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站托管、服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計、張灣網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

1、系統(tǒng)結(jié)構(gòu)概述

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

整個系統(tǒng)包含兩個物理節(jié)點:

  • Fabric節(jié)點:運行Fabric示例中的First Network,并且實例化了Fabcar鏈碼

  • API服務(wù)器節(jié)點:運行REST API Server代碼供外部訪問

下面是部署在AWS上的兩個節(jié)點實例的情況:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

首先參考官方文檔安裝hyperledger fabric。

然后運行腳本fabcar/startFabric.sh

cd fabric-samples/fabcar
./startFabric.sh

上述腳本運行之后,我們就得到一個正常運轉(zhuǎn)的Hyperledger Fabric網(wǎng)絡(luò)(著名的演示網(wǎng)絡(luò)First Network),包含2個機構(gòu)/4個對等節(jié)點,通道為mychannel,鏈碼Fabcar安裝在全部4個對等節(jié)點上并且在mychannel上激活。賬本中有10條車輛記錄,這是調(diào)用合約的initLedger方法的結(jié)果。

現(xiàn)在我們?yōu)镽EST API Server準備身份標識數(shù)據(jù)。使用fabcar/javascript創(chuàng)建一個用戶標識user1,我們將在REST API Server中使用這個身份標識:

cd javascript
npm install
node enrollAdmin.js
node registerUser.js
ls wallet/user1

運行結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

現(xiàn)在Rest API Server需要的東西都備齊了:

  • org1的連接配置文件:first-network/connection-org1.json

  • Node.js包文件:fabcar/package.json

  • User1身份錢包:fabcar/javascript/wallet/user1/

后面我們會把這些數(shù)據(jù)文件拷貝到Rest API Server。

2、Rest API Server設(shè)計

我們使用ExressJS來開發(fā)API服務(wù),利用query.js和invoke.js中的代碼實現(xiàn)與fabric交互的邏輯。API設(shè)計如下:

  • GET /api/queryallcars:返回全部車輛記錄

  • GET /api/query/CarID:返回指定ID的車輛記錄

  • POST /api/addcar/:添加一條新的車輛記錄

  • PUT /api/changeowner/CarID:修改指定ID的車輛記錄

3、Rest API Server代碼實現(xiàn)

apiserver.js代碼如下:

var bodyParser = require('body-parser');

var app = express();
app.use(bodyParser.json());

// Setting for Hyperledger Fabric
const { FileSystemWallet, Gateway } = require('fabric-network');
const path = require('path');
const ccpPath = path.resolve(__dirname, '.',  'connection-org1.json');


app.get('/api/queryallcars', async function (req, res) {
    try {

        // Create a new file system based wallet for managing identities.
        const walletPath = path.join(process.cwd(), 'wallet');
        const wallet = new FileSystemWallet(walletPath);
        console.log(`Wallet path: ${walletPath}`);

        // Check to see if we've already enrolled the user.
        const userExists = await wallet.exists('user1');
        if (!userExists) {
            console.log('An identity for the user "user1" does not exist in the wallet');
            console.log('Run the registerUser.js application before retrying');
            return;
        }

        // Create a new gateway for connecting to our peer node.
        const gateway = new Gateway();
        await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: false } });

        // Get the network (channel) our contract is deployed to.
        const network = await gateway.getNetwork('mychannel');

        // Get the contract from the network.
        const contract = network.getContract('fabcar');

        // Evaluate the specified transaction.
        // queryCar transaction - requires 1 argument, ex: ('queryCar', 'CAR4')
        // queryAllCars transaction - requires no arguments, ex: ('queryAllCars')
        const result = await contract.evaluateTransaction('queryAllCars');
        console.log(`Transaction has been evaluated, result is: ${result.toString()}`);
        res.status(200).json({response: result.toString()});

    } catch (error) {
        console.error(`Failed to evaluate transaction: ${error}`);
        res.status(500).json({error: error});
        process.exit(1);
    }
});


app.get('/api/query/:car_index', async function (req, res) {
    try {

        // Create a new file system based wallet for managing identities.
        const walletPath = path.join(process.cwd(), 'wallet');
        const wallet = new FileSystemWallet(walletPath);
        console.log(`Wallet path: ${walletPath}`);

        // Check to see if we've already enrolled the user.
        const userExists = await wallet.exists('user1');
        if (!userExists) {
            console.log('An identity for the user "user1" does not exist in the wallet');
            console.log('Run the registerUser.js application before retrying');
            return;
        }

        // Create a new gateway for connecting to our peer node.
        const gateway = new Gateway();
        await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: false } });

        // Get the network (channel) our contract is deployed to.
        const network = await gateway.getNetwork('mychannel');

        // Get the contract from the network.
        const contract = network.getContract('fabcar');

        // Evaluate the specified transaction.
        // queryCar transaction - requires 1 argument, ex: ('queryCar', 'CAR4')
        // queryAllCars transaction - requires no arguments, ex: ('queryAllCars')
        const result = await contract.evaluateTransaction('queryCar', req.params.car_index);
        console.log(`Transaction has been evaluated, result is: ${result.toString()}`);
        res.status(200).json({response: result.toString()});

    } catch (error) {
        console.error(`Failed to evaluate transaction: ${error}`);
        res.status(500).json({error: error});
        process.exit(1);
    }
});

app.post('/api/addcar/', async function (req, res) {
    try {

        // Create a new file system based wallet for managing identities.
        const walletPath = path.join(process.cwd(), 'wallet');
        const wallet = new FileSystemWallet(walletPath);
        console.log(`Wallet path: ${walletPath}`);

        // Check to see if we've already enrolled the user.
        const userExists = await wallet.exists('user1');
        if (!userExists) {
            console.log('An identity for the user "user1" does not exist in the wallet');
            console.log('Run the registerUser.js application before retrying');
            return;
        }

        // Create a new gateway for connecting to our peer node.
        const gateway = new Gateway();
        await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: false } });

        // Get the network (channel) our contract is deployed to.
        const network = await gateway.getNetwork('mychannel');

        // Get the contract from the network.
        const contract = network.getContract('fabcar');

        // Submit the specified transaction.
        // createCar transaction - requires 5 argument, ex: ('createCar', 'CAR12', 'Honda', 'Accord', 'Black', 'Tom')
        // changeCarOwner transaction - requires 2 args , ex: ('changeCarOwner', 'CAR10', 'Dave')
        await contract.submitTransaction('createCar', req.body.carid, req.body.make, req.body.model, req.body.colour, req.body.owner);
        console.log('Transaction has been submitted');
        res.send('Transaction has been submitted');

        // Disconnect from the gateway.
        await gateway.disconnect();

    } catch (error) {
        console.error(`Failed to submit transaction: ${error}`);
        process.exit(1);
    }
})

app.put('/api/changeowner/:car_index', async function (req, res) {
    try {

        // Create a new file system based wallet for managing identities.
        const walletPath = path.join(process.cwd(), 'wallet');
        const wallet = new FileSystemWallet(walletPath);
        console.log(`Wallet path: ${walletPath}`);

        // Check to see if we've already enrolled the user.
        const userExists = await wallet.exists('user1');
        if (!userExists) {
            console.log('An identity for the user "user1" does not exist in the wallet');
            console.log('Run the registerUser.js application before retrying');
            return;
        }

        // Create a new gateway for connecting to our peer node.
        const gateway = new Gateway();
        await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: false } });

        // Get the network (channel) our contract is deployed to.
        const network = await gateway.getNetwork('mychannel');

        // Get the contract from the network.
        const contract = network.getContract('fabcar');

        // Submit the specified transaction.
        // createCar transaction - requires 5 argument, ex: ('createCar', 'CAR12', 'Honda', 'Accord', 'Black', 'Tom')
        // changeCarOwner transaction - requires 2 args , ex: ('changeCarOwner', 'CAR10', 'Dave')
        await contract.submitTransaction('changeCarOwner', req.params.car_index, req.body.owner);
        console.log('Transaction has been submitted');
        res.send('Transaction has been submitted');

        // Disconnect from the gateway.
        await gateway.disconnect();

    } catch (error) {
        console.error(`Failed to submit transaction: ${error}`);
        process.exit(1);
    }	
})

app.listen(8080);

代碼中對原來fabcar的query.js和invoke.js修改如下:

  • ccpPath修改為當前目錄,因為我們要使用同一路徑下的連接配置文件connection-org1.json

  • 在gateway.connect調(diào)用中,修改選項discovery.asLocalhost為false

4、Rest API Server的連接配置文件

API服務(wù)依賴于連接配置文件來正確連接fabric網(wǎng)絡(luò)。文件 connection-org1.json 可以直接從 fabric網(wǎng)絡(luò)中獲取:

{
    "name": "first-network-org1",
    "version": "1.0.0",
    "client": {
        "organization": "Org1",
        "connection": {
            "timeout": {
                "peer": {
                    "endorser": "300"
                }
            }
        }
    },
    "organizations": {
        "Org1": {
            "mspid": "Org1MSP",
            "peers": [
                "peer0.org1.example.com",
                "peer1.org1.example.com"
            ],
            "certificateAuthorities": [
                "ca.org1.example.com"
            ]
        }
    },
    "peers": {
        "peer0.org1.example.com": {
            "url": "grpcs://localhost:7051",
            "tlsCACerts": {
                "pem": "-----BEGIN CERTIFICATE-----\nMIICVjCCAf2gAwIBAgIQEB1sDT11gzTv0/N4cIGoEjAKBggqhkjOPQQDA
jB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGF
tcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0xOTA5MDQwMjQzMDBaFw0yOTA5MDEwMjQz\nMDBaMHYxCzAJB
gNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tM
R8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEoN0qd5hM2SDfvGzNjTCXuQqyk+X
K4VISa16/y9iXBPpa0onyAXJuv7T0\noPf+mh4T7/g8uYtV2bwTpT2XFO3Q6KNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGA
QUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCCalpyChmrLtpgOll6TVmlMOO/2iiyI2PadNPsIYx51mTAKBggqh
kjOPQQD\nAgNHADBEAiBLNoAYWe9LvoxxBxl3sUM64kl7rx6dI3JU+dJG6FRxWgIgCu1ONEyp\nfux9lZWr6gcrIdsn/8fQuWiOIbAgq0HSr60
=\n-----END CERTIFICATE-----\n"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org1.example.com",
                "hostnameOverride": "peer0.org1.example.com"
            }
        },
        "peer1.org1.example.com": {
            "url": "grpcs://localhost:8051",
            "tlsCACerts": {
                "pem": "-----BEGIN CERTIFICATE-----\nMIICVjCCAf2gAwIBAgIQEB1sDT11gzTv0/N4cIGoEjAKBggqhkjOPQQDA
jB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGF
tcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0xOTA5MDQwMjQzMDBaFw0yOTA5MDEwMjQz\nMDBaMHYxCzAJB
gNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tM
R8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEoN0qd5hM2SDfvGzNjTCXuQqyk+X
K4VISa16/y9iXBPpa0onyAXJuv7T0\noPf+mh4T7/g8uYtV2bwTpT2XFO3Q6KNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGA
QUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCCalpyChmrLtpgOll6TVmlMOO/2iiyI2PadNPsIYx51mTAKBggqh
kjOPQQD\nAgNHADBEAiBLNoAYWe9LvoxxBxl3sUM64kl7rx6dI3JU+dJG6FRxWgIgCu1ONEyp\nfux9lZWr6gcrIdsn/8fQuWiOIbAgq0HSr60
=\n-----END CERTIFICATE-----\n"
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer1.org1.example.com",
                "hostnameOverride": "peer1.org1.example.com"
            }
        }
    },
    "certificateAuthorities": {
        "ca.org1.example.com": {
            "url": "https://localhost:7054",
            "caName": "ca-org1",
            "tlsCACerts": {
                "pem": "-----BEGIN CERTIFICATE-----\nMIICUTCCAfegAwIBAgIQSiMHm4n9QvhD6wltAHkZPTAKBggqhkjOPQQDA
jBzMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGF
tcGxlLmNvbTEcMBoGA1UEAxMTY2Eu\nb3JnMS5leGFtcGxlLmNvbTAeFw0xOTA5MDQwMjQzMDBaFw0yOTA5MDEwMjQzMDBa\nMHMxCzAJBgNVB
AYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T\nYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMRwwG
gYDVQQD\nExNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nz93lOhLJG93uJQgnh93QcPPal5NQXQnAutF
KYkun/eMHMe23wNPd0aJhnXdCjWF8\nMRHVAjtPn4NVCJYiTzSAnaNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1UdJQQWMBQG\nCCsGAQUFBwMCB
ggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCDK\naDhLwl3RBO6eKgHh5lHJovIyDJO3jTNb1ix1W86bFjAKBggqhkjOPQQDA
gNIADBF\nAiEA8KTKkjQwb1TduTWWkmsLmKdxrlE6/H7CfsdeGE+onewCIHJ1S0nLhbWYv+G9\nTbAFlNCpqr0AQefaRT3ghdURrlbo\n-----
END CERTIFICATE-----\n"
            },
            "httpOptions": {
                "verify": false
            }
        }
    }
}

當fabcar/startFabric.sh執(zhí)行時,我們可以交叉檢查證書的傳播是否正確。 peer0.org1和 peer1.org1 的證書是org1的 TLS root CA 證書簽名的。

注意所有的節(jié)點都以localhost引用,我們稍后會將其修改為Fabric Node的公開IP地址。

5、用戶身份標識

我們已經(jīng)在Fabric節(jié)點上生成了一個用戶標識user1并保存在wallet目錄中,我們可以看到有三個對應(yīng)的文件:私鑰、公鑰和證書對象:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

稍后我們會把這些文件拷貝到Rest API Server上。

6、安裝Rest API Server節(jié)點

1、首先在Rest API Server節(jié)點上安裝npm、node:

sudo apt-get update
sudo apt install curl
curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
sudo apt install -y nodejs
sudo apt-get install build-essentialnode -v
npm -v

驗證結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

2、然后在Rest API Server上創(chuàng)建一個目錄:

mkdir apiserver
cd apiserver

3、接下來將下面的文件從Fabric節(jié)點拷貝到Rest API Server節(jié)點。我們 利用loccalhost在兩個EC2實例間拷貝:

# localhost (update your own IP of the two servers)
# temp is an empty directory
cd temp
scp -i ~/Downloads/aws.pem ubuntu@[Fabric-Node-IP]:/home/ubuntu/fabric-samples/first-network/connection-org1.json .
scp -i ~/Downloads/aws.pem ubuntu@[Fabric-Node-IP]:/home/ubuntu/fabric-samples/fabcar/javascript/package.json .
scp -r -i ~/Downloads/aws.pem ubuntu@[Fabric-Node-IP]:/home/ubuntu/fabric-samples/fabcar/javascript/wallet/user1/ .
scp -r -i ~/Downloads/aws.pem * ubuntu@[API-Server-Node-IP]:/home/ubuntu/apiserver/

運行結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

4、可以看到現(xiàn)在所有的文件都拷貝到Rest API Server了,為了保持一致,我們將user1/改名為wallet/user1/:

cd apiserver
mkdir wallet
mv user1 wallet/user1

運行結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

5、現(xiàn)在在Rest API Server上創(chuàng)建上面的apiserver.js文件。

6、修改連接配置文件connection-org1.json 中的fabric節(jié)點的ip地址:

sed -i 's/localhost/[Fabric-Node-IP]/g' connection-org1.json

運行結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

7、在/etc/hosts中增加條目以便可以正確解析fabric節(jié)點的IP:

127.0.0.1 localhost
[Fabric-Node-IP] orderer.example.com
[Fabric-Node-IP] peer0.org1.example.com
[Fabric-Node-IP] peer1.org1.example.com
[Fabric-Node-IP] peer0.org2.example.com
[Fabric-Node-IP] peer1.org2.example.com

運行結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

8、安裝必要的依賴包:

npm install
npm install express body-parser --save

9、萬事俱備,啟動Rest API Server:

node apiserver.js

7、訪問API

我們的API服務(wù)在8080端口監(jiān)聽,在下面的示例中,我們使用curl來 演示如何訪問。

1、查詢所有車輛記錄

curl http://[API-Server-Node-IP]:8080/api/queryallcars

運行結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

2、添加新的車輛記錄并查詢

curl -d '{"carid":"CAR12","make":"Honda","model":"Accord","colour":"black","owner":"Tom"}' -H "Content-Type: application/json" -X POST http://[API-Server-Node-IP]:8080/api/addcar

curl http://[API-Server-Node-IP]:8080/api/query/CAR12

運行結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

3、修改車輛所有者并再次查詢

curl http://[API-Server-Node-IP]:8080/api/query/CAR4

curl -d '{"owner":"KC"}' -H "Content-Type: application/json" -X PUT http://[API-Server-Node-IP]:8080/api/changeowner/CAR4

curl http://[API-Server-Node-IP]:8080/api/query/CAR4

運行結(jié)果如下:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

我們也可以用postman得到同樣的結(jié)果:

如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器

以上是“如何利用Hyperledger Fabric的SDK來開發(fā)REST API服務(wù)器”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

分享文章:如何利用HyperledgerFabric的SDK來開發(fā)RESTAPI服務(wù)器
網(wǎng)站網(wǎng)址:http://newbst.com/article48/jhceep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站網(wǎng)站收錄網(wǎng)站策劃App開發(fā)網(wǎng)站導(dǎo)航Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管