Tangle分析工具 === # tool 目的 ## 有 coordinator ### 觀察 milestone 從 milestone 在 Tnagle 上的位置去了解那些交易不會指向 , 哪些交易 milestone會驗證 ## 沒有 coordinator ### 交易的確認 觀察在 Tangle 的一筆交易 , tip 驗證的比例隨時間的變化以及增加1%確認度的機率 ### 衝突交易及相關 bundle 觀察有衝突交易的情況 , 新issue的交易如何指向 tip ### 交易的累積權重 觀察在 Tangle 的一筆交易 , 累積權重隨時間的變化 ### random walk 選到 tip 的機率 從顯示選到 tip 的機率可以觀察 tip selection 對 Tangle 的影響 # 預計功能 ## 操作 ### 主畫面 ![](https://i.imgur.com/EBYwXGc.png) ### Node management ### node Tangle analysis ![](https://i.imgur.com/ZgFcAkw.png) #### node information ##### subtangle * live 從 $getTips$ 所得到的 tip , 畫出接下來 issue 的交易(新 tips) * 可以從驗證的方向或被驗證的方向畫出DAG * 可以在Tangle標示交易的狀態 交易狀態的示意圖: ```graphviz digraph init{ rankdir=RL; a[ label="c" color=yellow, fontcolor=yellow, fontsize=24, shape=box style = filled]; b[label="C1" color=black, fontcolor=red, fontsize=24, shape=box ]; c[label="C1" color=green, fontcolor=red, fontsize=24, shape=box style = filled] e[label="e" color=green, fontcolor=green, fontsize=24, shape=box style = filled] d[label="B3" color=black, fontcolor=blue, fontsize=24, shape=box] 21[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 11[label="" color=yellow, fontcolor=yellow, fontsize=24, shape=box style = filled] 31[label="B2" color=black, fontcolor=blue, fontsize=24, shape=box] 22[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 12[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 32[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 41[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 23[label="" color=gray, fontcolor=black, fontsize=24, shape=box style = filled] 13[label="" color=gray, fontcolor=blue, fontsize=24, shape=box style = filled] 42[label="B1" color=black, fontcolor=blue, fontsize=24, shape=box] 33[label="" color=gray, fontcolor=blue, fontsize=24, shape=box style = filled] a -> c; b -> c; a -> c; b -> c; e -> a; e -> a; d -> a; d -> b; 21->e; 21->d; 11->e; 11->e; 31->d; 31->d; 22->21; 22->31; 41->e; 41->d; 12->11; 12->21; 32->21; 32->31; 23->22; 23->32; 42->41; 42->31; 13->12; 13->22; 33->22; 33->42; } ``` 1. 黃色的長方形就是 milestone 2. 綠色的長方形是確認的交易 3. $\color{red}{C1}$ 代表第1組的衝突交易 4. $\color{blue}{B1}$ , $\color{blue}{B2}$ , $\color{blue}{B3}$ 代表同個 bundle , 不同的 bundle index 5. 灰色的長方形代表 tip * 是否需要其他的交易狀態?(ex:無效的bundle) #### 折線圖 * 交易隨著時間被驗證的 tip 比例 X-軸是時間或查詢次數 Y-軸是該交易被多少 tip 驗證的比例 * 交易的累積權重隨著時間的變化 X-軸是時間或查詢次數 Y-軸是該交易的累積權重 #### 統計 * random walk 在 subtangle 顯示 random walk 走到各交易的機率 * tip selection 在 subtangle 顯示每個 tip 被驗證的機率(一次 tip selection) * 交易被 tips 指向的比例 在 suntangle 顯示每個交易被多少比例的 tip 指向 ## 顯示 subtangle * 可以縮放 , 拖曳的 svg 用 svg 畫 subtangle ### 一些問題 1. 交易太多拖曳與縮放會變慢 2. 交易被其他交易遮擋 ## 額外功能 * subtangle 輸出圖檔 * 折線圖輸出圖檔 * subtangle 增長的動畫 * 選擇不同 net 的 node (server) , 可以同時觀察不同 net 上的 Tangle ## 要保留的 code ### 參考的commits * master [Highlighting approving nodes](https://github.com/DLTcollab/tangle-analytics/commit/cc5b913a094618d6d9495d030096d9b753add8cb) getAncestors() , getApprovingNodes() 保留 [Improved arrowhead behavior](https://github.com/DLTcollab/tangle-analytics/commit/c71bc84a5de0321ec8b602ac63ab244a101a3c38) generateLinkPath() 保留 [Added outline to hovered node](https://github.com/DLTcollab/tangle-analytics/commit/a89466ec71cc8d1acebb08acd861ec14a08ae73d) Node() 保留與選取特效 [Fixed right margin issue](https://github.com/DLTcollab/tangle-analytics/commit/3da77ddf96336779afc60cc64559171ae74f75fd) xFromTime() 函數會去掉 [Added weighted MCMC algorithm](https://github.com/DLTcollab/tangle-analytics/commit/ce419d575de580ca78501d6cf6e106e879f3a81c) test file 會去掉 , 剩下的算法保留 [Highlight descendents on mouse hover, added tests](https://github.com/DLTcollab/tangle-analytics/commit/5414649a18105d7b4045c49310b284fac0ff1be5) mouseEntersNodeHandler() 與 mouseLeavesNodeHandler() 會保留與改名 [Show tips in gray](https://github.com/DLTcollab/tangle-analytics/commit/e3ca87fe09a07feba16563e108d0b2ba1b1b61a9) getTips() 保留 [Window resize support](https://github.com/DLTcollab/tangle-analytics/commit/248d3fcdea9d2a92973a7d862406f872e081a486) 會去掉window的限制 [Links to approved nodes turn red](https://github.com/DLTcollab/tangle-analytics/commit/d7d334d372eeb4be31b0af6a59880377ae27108b) 保留被指向的交易是紅色的功能 [Tooltip over slider to show value](https://github.com/DLTcollab/tangle-analytics/commit/1db2fa1d16f434ed43299791bcc9443f8e77d972) 觀望 , 有些統計的功能可能需要用到 [Rescale x coordinates to cover window and stay in it](https://github.com/DLTcollab/tangle-analytics/commit/6259498c4d2f88e2c39f9631517545f87ef2b62b) 會去掉在window內的限制 * one-by-one [Confirmation confidence calculation](https://github.com/DLTcollab/tangle-analytics/commit/a593e26d9f3ae5d5fad1b3d4d1b78055d2c37c31) 觀望 # 資料來源 ## 用 findTransactions 拿取 ## 從 rocksDB 讀取 # 修改過程 [source code](https://github.com/KevinKu/iotavisualization/tree/remove_unnecessary_code) ### 模擬 Tangle 的圖 畫 Tangle 主要是這個[函數](https://github.com/KevinKu/iotavisualization/blob/master/src/components/Tangle.js#L116) [Node](https://github.com/KevinKu/iotavisualization/blob/master/src/components/Tangle.js#L78) 是 Tangle 中的交易 而在 [TangleContainer.js](https://github.com/KevinKu/iotavisualization/blob/master/src/containers/TangleContainer.js#L343) 中的code: ```javascript= <Tangle links={this.state.links} nodes={this.state.nodes} nodeCount={6} width={width} height={height} leftMargin={leftMargin} rightMargin={rightMargin} nodeRadius={this.state.nodeRadius} mouseEntersNodeHandler={this.mouseEntersNodeHandler.bind(this)} mouseLeavesNodeHandler={this.mouseLeavesNodeHandler.bind(this)} approvedNodes={approved.nodes} approvedLinks={approved.links} approvingNodes={approving.nodes} approvingLinks={approving.links} hoveredNode={this.state.hoveredNode} tips={getTips({ nodes: this.state.nodes, links: this.state.links, })} showLabels={this.state.nodeRadius > showLabelsMinimumRadius ? true : false} /> ``` 可以看到 ```javascript= links={this.state.links} nodes={this.state.nodes} ``` 都是使用[TangleContainer](https://github.com/KevinKu/iotavisualization/blob/master/src/containers/TangleContainer.js#L114)的狀態(state) 所以只要在這元件下用setState()去修改nodes和links就可以畫出不同的Tangle ### 畫圖參數的格式 在[generateData.js](https://github.com/KevinKu/iotavisualization/blob/master/src/shared/generateData.js)可以找到相關的格式 nodes: ```javascript= { name: `${nodes.length}`, time, x: 300, y: 200, } ``` links: ```javascript= const links = []; links.push({source: node, target: tips[0]}); ``` [GenerateSubTangle](https://github.com/KevinKu/iotavisualization/blob/remove_unnecessary_code/src/shared/generateData.js#L4)改寫: ```javascript= let nodes = []; nodes.push({name:'0',time:'0',}); nodes.push({name:'1',time:'0.5',}); nodes.push({name:'2',time:'1',}); nodes.push({name:'3',time:'1.5',}); nodes.push({name:'4',time:'2',}); const links = []; links.push({source: nodes[1], target: nodes[0]}); links.push({source: nodes[2], target: nodes[0]}); links.push({source: nodes[2], target: nodes[1]}); links.push({source: nodes[3], target: nodes[2]}); links.push({source: nodes[3], target: nodes[1]}); links.push({source: nodes[4], target: nodes[3]}); links.push({source: nodes[4], target: nodes[2]}); return { nodes, links, }; ``` 這樣就能畫出這樣的圖: ![](https://i.imgur.com/IQEFCSZ.png) ### 點button新增交易 為了 $live$ 顯示新加入 $SubTangle$ 的 $tip$ 所做的修改 結果圖: ![](https://i.imgur.com/HXukTkU.png) ![](https://i.imgur.com/0cVAO7D.png) code: ```javascript= let tangle = ""; let c_nodes = this.state.nodes; let c_links = this.state.links; let c_count = this.state.count + 1; if(this.state.count == 0){ tangle = GenerateSubTangle({RootTransactionHash}); }else if(this.state.count == 1){ c_nodes.push({name:c_count.toString(),time:c_count.toString(),}); c_links.push({source: c_nodes[2], target: c_nodes[0]}); c_links.push({source: c_nodes[2], target: c_nodes[1]}); tangle = {nodes:c_nodes,links:c_links}; }else{ c_nodes.push({name:c_count.toString(),time:c_count.toString(),}); c_links.push({source: c_nodes[c_count], target: c_nodes[c_count - 2]}); c_links.push({source: c_nodes[c_count], target: c_nodes[c_count - 1]}); tangle = {nodes:c_nodes,links:c_links}; } ................................................................ this.setState({ nodes: tangle.nodes, links: tangle.links, nodeRadius, count: c_count, }, ... ) ``` ### Await無法使用 由[issue](https://github.com/iotaledger/iota.lib.js/issues/168)知道await之類不能使用 嘗試[curl-request](https://www.npmjs.com/package/curl-request)來跟node拿取資料 同事找到的可使用then的[library](https://github.com/jimthedev/iotap) 用以上的library可以使用 ![](https://i.imgur.com/c6z5dnj.png) ```javascript= const server_node = new IOTA({ 'host':'https://potato.iotasalad.org' , 'port':14265 }); const s_node = iotap.create(server_node); const approve_list = s_node.findTransactions({'approvees': ["9DCRWEHKAPXZJTISHACOVKLPLLVBHBHPKZUPSHZOEZTQQGXEBGXIVGFSSZYHBIGRPQZCVVSRYYMUZ9999"]}); Promise.all([approve_list]).then(([approve_list])=>{console.log(approve_list)}); ``` # SubTangle的算法 由於還有 paint milestone 與 paint confirmed transaction 的需求 以及 live 的選項 考慮以 setInterval 間隔1秒畫一次 approvees 的結果 預計node的格式 改成下列 ```json= {name:"",time:"",transactionHash:"",nodeIndex:"",} ``` 先實做只查詢一層 ![](https://i.imgur.com/FnaTRfq.png) 上圖是milestone的 ![](https://i.imgur.com/I2zKkfn.png) code: ```javascript= GraphSubTangle() { const nodeRadius = getNodeRadius(6); let c_subTangleTips = []; let c_nodes = []; c_nodes.push({name:'0',time:0,transactionHash:this.state.rootTransactionHash,nodeIndex:0,}); c_subTangleTips.push({name:'0',time:0,transactionHash:this.state.rootTransactionHash,nodeIndex:0,}); let ID = setInterval(()=>{this.DrawNextApprovees();},3000); this.setState({ nodes: c_nodes, links: [], subTangleTips: c_subTangleTips, time: 0, nodeRadius, intervalID: ID, live: 1, }, ); } DrawNextApprovees(){ const nodeRadius = getNodeRadius(6); let tangle = ""; let c_subTangleTips = []; let c_nodes = this.state.nodes; let c_links = this.state.links; let c_time = this.state.time + 0.2; let s_node = this.state.requestServer; if(this.state.live == 0){ return ; } if(this.state.subTangleTips.length > 0){ for(let findTransaction of this.state.subTangleTips){ const approve_list = s_node.findTransactions({'approvees': [findTransaction.transactionHash]}); Promise.all([approve_list]).then(([approve_list])=>{ if(approve_list.length > 0){ for(let a_transaction of approve_list){ let exist = 0; for(let site of c_nodes){ if(a_transaction == site.transactionHash){ exist = 1; } } if(exist == 0){ let c_nodeIndex = c_nodes.length; c_nodes.push({name:c_nodeIndex.toString(),time:c_time,transactionHash:a_transaction,nodeIndex:c_nodeIndex,}); c_subTangleTips.push({name:c_nodeIndex.toString(),time:c_time,transactionHash:a_transaction,nodeIndex:c_nodeIndex,}); c_links.push({source:c_nodes[c_nodeIndex],target:c_nodes[findTransaction.nodeIndex]}); } } } }); } } tangle = {nodes:c_nodes,links:c_links}; console.log(c_subTangleTips); const {width, height} = this.state; for (let node of tangle.nodes) { node.y = height/4 + Math.random()*(height/2), node.x = width/2; // required to avoid annoying errors } this.force.stop(); this.setState({ nodes: tangle.nodes, links: tangle.links, subTangleTips: c_subTangleTips, time: c_time, nodeRadius, }, () => { // Set all nodes' x by time value after state has been set this.recalculateFixedPositions(); }); this.force.restart().alpha(1); return ; } ``` 接下來往拖曳跟縮放SVG圖來處理 ### 拖曳跟縮放SVG圖 使用這個[套件](https://github.com/chrvadala/react-svg-pan-zoom) 目前做出來的效果: ![](https://i.imgur.com/tItmRdS.png) 接下來想去掉d3 , 改成決定每筆交易在svg的位置 ![](https://i.imgur.com/xXIV2fp.png) 回覆了指向與被指向的標示 預計加入三類Components [span]() [Text Fields](https://material-ui.com/demos/text-fields/) [Switches with FormGroup](https://material-ui.com/demos/selection-controls/#switches-with-formgroup) 三類分別對應 $\color{blue}{span}$ : ![](https://i.imgur.com/sapKWRB.png) $\color{blue}{Text \space Fields}$ : 搜尋在 Tangle 內的交易 ![](https://i.imgur.com/IQf7lc6.png) 管理與繪製 Tangle ![](https://i.imgur.com/iOKZXUR.png) $\color{blue}{Switches with FormGroup}$ : ![](https://i.imgur.com/kSDRfhI.png) # 11/15 [TangleManagement.js](https://github.com/DLTcollab/tangle-analytics/blob/master/src/components/TangleManagement.js) 可以在瀏覽器顯示 ![](https://i.imgur.com/b0dJ4hF.png) 寫了 [TangleManagementContainer.js](https://github.com/DLTcollab/tangle-analytics/blob/master/src/containers/TangleManagementContainer.js)並可以在瀏覽器上顯示 ![](https://i.imgur.com/ibQ89JO.png) 接下來要把 Graph , STOP , CARRY ON 功能補完 # 11/16 ![](https://i.imgur.com/4doxCoN.png) 交易 Hash 可以輸入字串 目前 nodes 與 links 無法正確顯示 DAG 的結構 不過逐漸把 TangleContainer 的功能拆解 另外 , IOTA node 的 object 需要另一個 Container 來處理 找到的[svg 縮放 tool](https://github.com/ganxunzou/react-resize-svg) , 等拆解完後來測測看 # 12/8 來重構 $GraphTangle$ 與 $GetNextApprovees$ 兩個函數 先講原本的實作有什麼問題 ## 某些DAG的結構不對 這算是原本算法的 bug 以一個 Tangle 為例子: ```graphviz digraph init{ rankdir=RL; a[ label="a" color=blue, fontcolor=blue, fontsize=24, shape=box]; c[label="c" color=blue, fontcolor=blue, fontsize=24, shape=box] d[label="d" color=blue, fontcolor=blue, fontsize=24, shape=box] e[label="e" color=blue, fontcolor=blue, fontsize=24, shape=box] c -> a; c -> a; d -> a; d -> a; e->d; e->c; } ``` 當 Tangle 是上圖時 , $d$ 與 $e$ 的連線會沒有紀錄到 因為查詢 $c$ 的時候 , $e$ 會被加到 nodes 接下來來查詢 $d$ 的時候 , 由於 $e$ 已經在 nodes 了 所以就換下一個直接驗證的交易 , 這樣 $d$ 與 $e$ 的連線就沒有加到 links 所以圖畫出來就不對了 ## 無法補畫 lazy tip 整個畫圖的邏輯 , 是從 subTangle 的 tips 找出直接驗證 tips 的交易畫出來的 這會使 lazy tip 不會被查詢到 所以 lazy tip 不會被畫出來 # 1/4 先補輸入 node url 與 port 的欄位 因為 new IOTA() 的建構函數需要 結果: ![](https://i.imgur.com/SLPZgbl.png) # 1/10 測試之前輸入 node 的 UI 並寫了一個測試用的按鈕 ![](https://i.imgur.com/ioJKEra.png) 接下來要重寫 GetNextApprovees 與 GraphTangle # 1/11 由於要重寫渲染 Tangle 的函數 需要重新定義 node(交易) 的格式 然後刪除了一個變數(subTangleTip) 讓 TangleManagementContainer 單純查詢 Tangle 幾個關於格式的問題 1. 每個 node 要不要有高度? # 1/15 關於 node 要不要有高度 我想是要的 , 因為在畫 Tangle 的時候 , 應該會重用 IF 模擬的函數 函數會使用到 time 這個參數 , 預計用高度把 time 取代掉 由於 IF 模擬的函數有使用 d3 的 force layout , 可以避免兩筆交易重疊的情況 目前 node(交易) 的格式定成這樣: ```javascript= {name:"",height:0,nodeIndex:0,} ``` 解釋每個欄位的意思 * name : 存放交易 hash , 這欄位就之前測試結果 , 是必須的 * height : 高度 , 從 TangleRoot 開始算起 , 定義白皮書有提到 * nodeIndex : 建構 links 時使用 , 意義是某個交易 hash 在 nodes 的 index 然後測試的時候發現了 clear 這個功能沒寫好 , 順便 fix 了 [fix clear and rewrite GraphTangle](https://github.com/DLTcollab/tangle-analytics/commit/85450278072d30d0643343b2f3b898a618f34e27) # 1/17 and 1/18 寫一下要處理的四種狀況 講一下前提 用某個交易 hash , 去跟 node 查詢直接驗證的交易 會得到一組交易 hash 的列表 這邊討論的是這直接驗證交易的交易列表 , 取出其中一筆交易 與查詢傳入的交易之間的關係 會有四種情況 , 以下討論 ## nodes 沒有 , links 沒有 :::info 標準的新交易的情況 所以要加入到nodes 要加入驗證關係到links 然後高度直接計算 就是被驗證的交易高度+1 ::: ## nodes 有 , links 沒有 :::info 這代表links紀錄到trunk或branch 但還有缺少的直接驗證關係 所以要補links 然後要檢查高度要不要做更新 每筆交易高度的算法都是取trunk或branch最高的加一 ::: ## nodes 有 , links 有 :::info 代表目前交易與被直接驗證交易的組合沒有變化 所以什麼都不做 , 直接跳過 ::: ## nodes 沒有 , links 有 :::info 這種是不可能的 , 不考慮 ::: # 1/23 更新完成 [Finish create nodes and links function](https://github.com/DLTcollab/tangle-analytics/commit/22774909f8f7318eb038b7cc89235abac5e9c620) 在想要如何測試 測試一個菱形的DAG TangleRoot: ``` ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999 ``` 發起一筆新的 , 直接驗證到 TangleRoot ``` 9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999 ``` 看測試的結果 nodes: ``` (2) [{…}, {…}] 0 : height : 0 name : "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999" nodeIndex : 0 __proto__ : Object 1 : height : 1 name : "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999" nodeIndex : 1 __proto__ : Object length : 2 __proto__ : Array(0) ``` links: ``` : source : {name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1} target : {name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0} __proto__ : Object length : 1 __proto__ : Array(0) ``` 再發一筆驗證到 TangleRoot的交易 ``` WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999 ``` 看測試的結果 nodes: ``` (3) [{…}, {…}, {…}] 0 : {name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0} 1 : {name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1} 2 : {name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2} length : 3 __proto__ : Array(0) ``` links: ``` (2) [{…}, {…}] 0: source:{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1} target:{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0} __proto__ : Object 1: source:{name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2} target:{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0} __proto__ : Object length : 2 __proto__ : Array(0) ``` 所以有兩筆指向 tangleRoot 而 links 所紀錄的指向關係也沒錯 現在再發一筆交易 , 指向 "WW9..." 與 "9QV..." 交易 hash: ``` HZGTOLSBLMJGFWRGPOJOKUDLFTJDNSLTJOORCSIWKHTNJGOYDVDGWPXTZXZNPVFALIOOXOXPZYBE99999 ``` 發現 links 的數量不對 進一步追查是 doesLinkExist 不會被賦值為1 代表檢查 link 有沒有在 links 有問題 修改了檢查 links 的 [code](https://github.com/DLTcollab/tangle-analytics/commit/ba0b4096c362851cbf1d293e33b5ce9e1987d57d): ```javascript= for(let Link of Links){ if(Link.source == Nodes[approverNodeIndex] && Link.target == searchedTransaction){ doesLinkExist = 1; } } ``` 重新測試菱形的情況 nodes: ``` (4) [{…}, {…}, {…}, {…}] 0 : {name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0} 1 : {name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1} 2 : {name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2} 3 : {name: "HZGTOLSBLMJGFWRGPOJOKUDLFTJDNSLTJOORCSIWKHTNJGOYDVDGWPXTZXZNPVFALIOOXOXPZYBE99999", height: 2, nodeIndex: 3} length : 4 ``` links: ``` (4) [{…}, {…}, {…}, {…}] 0 : source:{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1} target:{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0} __proto__ : Object 1 : source:{name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2} target:{name: "ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999", height: 0, nodeIndex: 0} __proto__ : Object 2 : source:{name: "HZGTOLSBLMJGFWRGPOJOKUDLFTJDNSLTJOORCSIWKHTNJGOYDVDGWPXTZXZNPVFALIOOXOXPZYBE99999", height: 2, nodeIndex: 3} target:{name: "WW9UDZZEZOOTESXPZVENITKCBVRZU9QIJXWBIYAYRDPJJ9IFFUETKFJRFKJE9VVQCSUZIVLIGJOWZ9999", height: 1, nodeIndex: 2} __proto__ : Object 3 : source:{name: "HZGTOLSBLMJGFWRGPOJOKUDLFTJDNSLTJOORCSIWKHTNJGOYDVDGWPXTZXZNPVFALIOOXOXPZYBE99999", height: 2, nodeIndex: 3} target:{name: "9QVMIWKBDERDVKEPZVSZHCRTCJSQDYVQHBTPXF9DXVQAEUSEPHEDXCMLYCTLHGONZHBPRNKTRPJVA9999", height: 1, nodeIndex: 1} __proto__ : Object length : 4 ``` links 也沒有重複的元素 , 且都紀錄到了正確的驗證關係 又多送直接驗證到 “WW9…” 與 “9QV…” 的交易 一樣沒錯 ![](https://i.imgur.com/KIwTFnf.png) 測試用的[TangleRoot](https://thetangle.org/transaction/ONREFCNKRLGLVEODAMCRNXFBAJEUWQTHL9I9W9AMZEBPUDDVAJSYVLJMZWCWPJLDWQBVQWGQNESGZ9999) # 1/24 開始處理 Tangle 的[顯示](https://hackmd.io/s/HJmfL5c0f#subtangle) 構想如下 ![](https://i.imgur.com/naYMRWX.png) 用 redux 傳 nodes 與 links 然後 TangleContainer 要包含控制顯示的部份 舉個例子 ```graphviz digraph init{ rankdir=RL; a[ label="c" color=yellow, fontcolor=yellow, fontsize=24, shape=box style = filled]; b[label="C1" color=black, fontcolor=red, fontsize=24, shape=box ]; c[label="C1" color=green, fontcolor=red, fontsize=24, shape=box style = filled] e[label="e" color=green, fontcolor=green, fontsize=24, shape=box style = filled] d[label="B3" color=black, fontcolor=blue, fontsize=24, shape=box] 21[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 11[label="" color=yellow, fontcolor=yellow, fontsize=24, shape=box style = filled] 31[label="B2" color=black, fontcolor=blue, fontsize=24, shape=box] 22[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 12[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 32[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 41[label="" color=black, fontcolor=blue, fontsize=24, shape=box] 23[label="" color=gray, fontcolor=black, fontsize=24, shape=box style = filled] 13[label="" color=gray, fontcolor=blue, fontsize=24, shape=box style = filled] 42[label="B1" color=black, fontcolor=blue, fontsize=24, shape=box] 33[label="" color=gray, fontcolor=blue, fontsize=24, shape=box style = filled] a -> c; b -> c; a -> c; b -> c; e -> a; e -> a; d -> a; d -> b; 21->e; 21->d; 11->e; 11->e; 31->d; 31->d; 22->21; 22->31; 41->e; 41->d; 12->11; 12->21; 32->21; 32->31; 23->22; 23->32; 42->41; 42->31; 13->12; 13->22; 33->22; 33->42; } ``` 以上是全部標示 可以選擇不讓 milestone 顯示出來 那黃色的交易就會變成白色 目前先讓 Redux 可以正確運作 [Redux基礎](https://chentsulin.github.io/redux/docs/basics/index.html) # 1/25 發現更簡單的作法:[helper class](https://medium.com/@chachameow/reactjs%E5%AD%B8%E7%BF%92%E7%AD%86%E8%A8%98-component%E9%96%93%E5%82%B3%E5%80%BC-53fbd469132e) 先用這個方法來處理 新的 [commit](https://github.com/DLTcollab/tangle-analytics/commit/7a73c64fd6c2c29089959d89eee448aa003790a9) 結果: ![](https://i.imgur.com/6HDfJEn.png) nodes 和 links 有正確傳給 TangleContainer 但由於每個 node 的 x,y 座標沒給 , 所以圖畫不出來 現在會先來改寫 TangleContainer , 把控制顯示與 d3 加進去 # 2/15 考慮重寫 GetNextApprovees 格式想重新定義 理由是這樣的 由於 Tangle 繪圖是依賴 nodes 和 links , 而原本的 nodes 會被修改 , 以便在畫 rect 時可以根據顯示條件來做更改 例如要不要標示交易是否確認 所以 links 也會要做更改 既然是跟顯示相關 TangleManagementContainer也不需要 links 而是紀錄交易 list 丟給 TangleContainer TangleContainer 在依據顯示的要求 , 去生成 nodes 與 links ###### tags: `IOTA`