VOTING POWER100.00%
DOWNVOTE POWER100.00%
RESOURCE CREDITS100.00%
REPUTATION PROGRESS0.00%
Net Worth
29.326USD
HIVE
0.036HIVE
HBD
30.611HBD
Own HP
23.280HP
Detailed Balance
| HIVE | ||
| balance | 0.036HIVE | HIVE |
| market_balance | 0.000HIVE | HIVE |
| savings_balance | 0.000HIVE | HIVE |
| reward_hive_balance | 5.550HIVE | HIVE |
| HIVE POWER | ||
| Own HP | 23.280HP | HP |
| Delegated Out | 0.000HP | HP |
| Delegation In | 0.000HP | HP |
| Effective Power | 23.280HP | HP |
| Reward HP (pending) | 5.552HP | HP |
| HBD | ||
| hbd_balance | 30.611HBD | HBD |
| hbd_conversions | 0.000HBD | HBD |
| hbd_market_balance | 0.000HBD | HBD |
| savings_hbd_balance | 0.000HBD | HBD |
| reward_hbd_balance | 0.000HBD | HBD |
{
"balance": "0.036 HIVE",
"savings_balance": "0.000 HIVE",
"reward_hive_balance": "5.550 HIVE",
"vesting_shares": "37790.211291 VESTS",
"delegated_vesting_shares": "0.000000 VESTS",
"received_vesting_shares": "0.000000 VESTS",
"hbd_balance": "30.611 HBD",
"savings_hbd_balance": "0.000 HBD",
"reward_hbd_balance": "0.000 HBD"
}Account Info
| name | acidsound |
| id | 217625 |
| rank | 0 |
| reputation | 0 |
| created | 2017-06-23T18:26:21 |
| recovery_account | steem |
| proxy | None |
| invited_by | null |
| post_count | 35 |
| comment_count | 0 |
| lifetime_vote_count | 0 |
| witnesses_voted_for | 0 |
| last_post | 2019-10-03T15:03:33 |
| last_root_post | 2019-10-03T15:03:33 |
| last_vote_time | 2020-02-10T14:35:30 |
| proxied_vsf_votes | 0, 0, 0, 0 |
| can_vote | 1 |
| voting_power | 9,413 |
| delayed_votes | None |
| governance_vote_expiration_ts | 1969-12-31T23:59:59 |
| balance | 0.036 HIVE |
| savings_balance | 0.000 HIVE |
| hbd_balance | 30.611 HBD |
| savings_hbd_balance | 0.000 HBD |
| vesting_shares | 37790.211291 VESTS |
| delegated_vesting_shares | 0.000000 VESTS |
| received_vesting_shares | 0.000000 VESTS |
| reward_vesting_balance | 10976.911249 VESTS |
| vesting_balance | 0.000 HIVE |
| vesting_withdraw_rate | 0.000000 VESTS |
| next_vesting_withdrawal | 1969-12-31T23:59:59 |
| withdrawn | 0 |
| to_withdraw | 0 |
| withdraw_routes | 0 |
| savings_withdraw_requests | 0 |
| last_account_recovery | 1970-01-01T00:00:00 |
| reset_account | null |
| last_owner_update | 1970-01-01T00:00:00 |
| last_account_update | 2019-03-31T17:54:00 |
| mined | No |
| hbd_seconds | 0 |
| hbd_last_interest_payment | 2018-12-01T13:35:09 |
| savings_hbd_last_interest_payment | 1970-01-01T00:00:00 |
{
"active": {
"account_auths": [],
"key_auths": [
[
"STM8HADVNSA94yRJ8b54Jrw5krBkDJQrmLcjmqw3nDW8tnis4LbY5",
1
]
],
"weight_threshold": 1
},
"balance": "0.036 HIVE",
"can_vote": true,
"comment_count": 0,
"created": "2017-06-23T18:26:21",
"curation_rewards": 2,
"delayed_votes": [],
"delegated_vesting_shares": "0.000000 VESTS",
"downvote_manabar": {
"current_mana": 9447552822,
"last_update_time": 1581345330
},
"governance_vote_expiration_ts": "1969-12-31T23:59:59",
"guest_bloggers": [],
"hbd_balance": "30.611 HBD",
"hbd_last_interest_payment": "2018-12-01T13:35:09",
"hbd_seconds": "0",
"hbd_seconds_last_update": "2018-12-01T13:35:09",
"id": 217625,
"json_metadata": "{\"profile\":{\"profile_image\":\"https://gravatar.com/avatar/c1f9e3fc81c451788df421e46fda5c21?size=400\",\"name\":\"acidsound\",\"about\":\"function과 reactive를 좋아하는 플루티스트\"}}",
"last_account_recovery": "1970-01-01T00:00:00",
"last_account_update": "2019-03-31T17:54:00",
"last_owner_update": "1970-01-01T00:00:00",
"last_post": "2019-10-03T15:03:33",
"last_root_post": "2019-10-03T15:03:33",
"last_vote_time": "2020-02-10T14:35:30",
"lifetime_vote_count": 0,
"market_history": [],
"memo_key": "STM82LaqLJ2DqX13NiYEFAucd1XVyHchG879nMYfXajBEgYkfJAfQ",
"mined": false,
"name": "acidsound",
"next_vesting_withdrawal": "1969-12-31T23:59:59",
"open_recurrent_transfers": 0,
"other_history": [],
"owner": {
"account_auths": [],
"key_auths": [
[
"STM5q6WPcZpvAvi6fLUmFbusAb7QL8LQniqjk71N6UpsFHHT56p7C",
1
]
],
"weight_threshold": 1
},
"pending_claimed_accounts": 0,
"pending_transfers": 0,
"post_bandwidth": 0,
"post_count": 35,
"post_history": [],
"post_voting_power": "37790.211291 VESTS",
"posting": {
"account_auths": [
[
"busy.app",
1
],
[
"ctube.app",
1
],
[
"dlive.app",
1
],
[
"drugwars.app",
1
],
[
"dtube.app",
1
]
],
"key_auths": [
[
"STM5vtTJdVuVcZetoHAsLatsv8y8foagwqLdPpbCCATzWXeJni9YG",
1
]
],
"weight_threshold": 1
},
"posting_json_metadata": "{\"profile\":{\"profile_image\":\"https://gravatar.com/avatar/c1f9e3fc81c451788df421e46fda5c21?size=400\",\"name\":\"acidsound\",\"about\":\"function과 reactive를 좋아하는 플루티스트\"}}",
"posting_rewards": 46653,
"previous_owner_update": "1970-01-01T00:00:00",
"proxied_vsf_votes": [
0,
0,
0,
0
],
"proxy": "",
"received_vesting_shares": "0.000000 VESTS",
"recovery_account": "steem",
"reputation": 0,
"reset_account": "null",
"reward_hbd_balance": "0.000 HBD",
"reward_hive_balance": "5.550 HIVE",
"reward_vesting_balance": "10976.911249 VESTS",
"reward_vesting_hive": "5.552 HIVE",
"savings_balance": "0.000 HIVE",
"savings_hbd_balance": "0.000 HBD",
"savings_hbd_last_interest_payment": "1970-01-01T00:00:00",
"savings_hbd_seconds": "0",
"savings_hbd_seconds_last_update": "1970-01-01T00:00:00",
"savings_withdraw_requests": 0,
"tags_usage": [],
"to_withdraw": 0,
"transfer_history": [],
"vesting_balance": "0.000 HIVE",
"vesting_shares": "37790.211291 VESTS",
"vesting_withdraw_rate": "0.000000 VESTS",
"vote_history": [],
"voting_manabar": {
"current_mana": 35573672319,
"last_update_time": 1581345330
},
"voting_power": 9413,
"withdraw_routes": 0,
"withdrawn": 0,
"witness_votes": [],
"witnesses_voted_for": 0,
"rank": 0
}Withdraw Routes
| Incoming | Outgoing |
|---|---|
Empty | Empty |
{
"incoming": [],
"outgoing": []
}From Date
To Date
vorygasent 0.001 HIVE to @acidsound- "UA_SOSAT"2026/03/14 22:42:57
vorygasent 0.001 HIVE to @acidsound- "UA_SOSAT"
2026/03/14 22:42:57
| to | acidsound |
| from | voryga |
| memo | UA_SOSAT |
| amount | 0.001 HIVE |
| Transaction Info | Block #104634987/Trx c2469c4f67d72dd06818f7e65e7dd78cf227c81a |
View Raw JSON Data
{
"op": [
"transfer",
{
"to": "acidsound",
"from": "voryga",
"memo": "UA_SOSAT",
"amount": "0.001 HIVE"
}
],
"block": 104634987,
"trx_id": "c2469c4f67d72dd06818f7e65e7dd78cf227c81a",
"op_in_trx": 0,
"timestamp": "2026-03-14T22:42:57",
"virtual_op": false,
"trx_in_block": 10
}engravesent 0.001 HIVE to @acidsound- "I've noticed you have a recovery account set to @steem, which is a security issue! Review your recovery account if you don't want to lose your tokens! Read more: https://peakd.com/witness-update/@engr..."2020/04/05 00:34:54
engravesent 0.001 HIVE to @acidsound- "I've noticed you have a recovery account set to @steem, which is a security issue! Review your recovery account if you don't want to lose your tokens! Read more: https://peakd.com/witness-update/@engr..."
2020/04/05 00:34:54
| to | acidsound |
| from | engrave |
| memo | I've noticed you have a recovery account set to @steem, which is a security issue! Review your recovery account if you don't want to lose your tokens! Read more: https://peakd.com/witness-update/@engrave/review-your-recovery-account-if-you-dont-want-to-lose-your-assets |
| amount | 0.001 HIVE |
| Transaction Info | Block #42260782/Trx 47b3edb9c8f3bc77b72a859ee52f4a3875ebcecf |
View Raw JSON Data
{
"op": [
"transfer",
{
"to": "acidsound",
"from": "engrave",
"memo": "I've noticed you have a recovery account set to @steem, which is a security issue! Review your recovery account if you don't want to lose your tokens! Read more: https://peakd.com/witness-update/@engrave/review-your-recovery-account-if-you-dont-want-to-lose-your-assets",
"amount": "0.001 HIVE"
}
],
"block": 42260782,
"trx_id": "47b3edb9c8f3bc77b72a859ee52f4a3875ebcecf",
"op_in_trx": 19,
"timestamp": "2020-04-05T00:34:54",
"virtual_op": false,
"trx_in_block": 4
}acidsoundeffective vote applied for @splex7 / crypto-com-invest-102020/02/10 14:35:33
acidsoundeffective vote applied for @splex7 / crypto-com-invest-10
2020/02/10 14:35:33
| voter | acidsound |
| author | splex7 |
| weight | 313 (3.13%) |
| rshares | 675993313 |
| permlink | crypto-com-invest-10 |
| pending payout | 0.056 HBD |
| total vote weight | 157070 |
| Transaction Info | Block #40699500/Trx c1a2712725b043b38f64a1e7ea02a4055c2145d4 |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "acidsound",
"author": "splex7",
"weight": 313,
"rshares": 675993313,
"permlink": "crypto-com-invest-10",
"pending_payout": "0.056 HBD",
"total_vote_weight": 157070
}
],
"block": 40699500,
"trx_id": "c1a2712725b043b38f64a1e7ea02a4055c2145d4",
"op_in_trx": 1,
"timestamp": "2020-02-10T14:35:33",
"virtual_op": true,
"trx_in_block": 19
}acidsoundupvoted (100.00%) @splex7 / crypto-com-invest-102020/02/10 14:35:33
acidsoundupvoted (100.00%) @splex7 / crypto-com-invest-10
2020/02/10 14:35:33
| voter | acidsound |
| author | splex7 |
| weight | 10000 (100.00%) |
| permlink | crypto-com-invest-10 |
| Transaction Info | Block #40699500/Trx c1a2712725b043b38f64a1e7ea02a4055c2145d4 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "acidsound",
"author": "splex7",
"weight": 10000,
"permlink": "crypto-com-invest-10"
}
],
"block": 40699500,
"trx_id": "c1a2712725b043b38f64a1e7ea02a4055c2145d4",
"op_in_trx": 0,
"timestamp": "2020-02-10T14:35:33",
"virtual_op": false,
"trx_in_block": 19
}2020/02/10 14:35:15
2020/02/10 14:35:15
| voter | acidsound |
| author | splex7 |
| weight | 216 (2.16%) |
| rshares | 690777369 |
| permlink | 7hdemp |
| pending payout | 0.448 HBD |
| total vote weight | 871139 |
| Transaction Info | Block #40699494/Trx 91141d97d65a4721f159b664034104c858025abd |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "acidsound",
"author": "splex7",
"weight": 216,
"rshares": 690777369,
"permlink": "7hdemp",
"pending_payout": "0.448 HBD",
"total_vote_weight": 871139
}
],
"block": 40699494,
"trx_id": "91141d97d65a4721f159b664034104c858025abd",
"op_in_trx": 1,
"timestamp": "2020-02-10T14:35:15",
"virtual_op": true,
"trx_in_block": 35
}2020/02/10 14:35:15
2020/02/10 14:35:15
| voter | acidsound |
| author | splex7 |
| weight | 10000 (100.00%) |
| permlink | 7hdemp |
| Transaction Info | Block #40699494/Trx 91141d97d65a4721f159b664034104c858025abd |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "acidsound",
"author": "splex7",
"weight": 10000,
"permlink": "7hdemp"
}
],
"block": 40699494,
"trx_id": "91141d97d65a4721f159b664034104c858025abd",
"op_in_trx": 0,
"timestamp": "2020-02-10T14:35:15",
"virtual_op": false,
"trx_in_block": 35
}2020/02/10 14:34:48
2020/02/10 14:34:48
| id | follow |
| json | ["follow",{"follower":"acidsound","following":"splex7","what":["blog"]}] |
| required auths | [] |
| required posting auths | ["acidsound"] |
| Transaction Info | Block #40699485/Trx 1aa6bb012efb89b9ab351022376a842b7c648f4b |
View Raw JSON Data
{
"op": [
"custom_json",
{
"id": "follow",
"json": "[\"follow\",{\"follower\":\"acidsound\",\"following\":\"splex7\",\"what\":[\"blog\"]}]",
"required_auths": [],
"required_posting_auths": [
"acidsound"
]
}
],
"block": 40699485,
"trx_id": "1aa6bb012efb89b9ab351022376a842b7c648f4b",
"op_in_trx": 0,
"timestamp": "2020-02-10T14:34:48",
"virtual_op": false,
"trx_in_block": 22
}2020/02/10 14:34:24
2020/02/10 14:34:24
| voter | acidsound |
| author | splex7 |
| weight | 264 (2.64%) |
| rshares | 705804226 |
| permlink | mco |
| pending payout | 0.249 HBD |
| total vote weight | 565698 |
| Transaction Info | Block #40699478/Trx 6623bff22ce1442081a70e2d025fe73f87e12fe1 |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "acidsound",
"author": "splex7",
"weight": 264,
"rshares": 705804226,
"permlink": "mco",
"pending_payout": "0.249 HBD",
"total_vote_weight": 565698
}
],
"block": 40699478,
"trx_id": "6623bff22ce1442081a70e2d025fe73f87e12fe1",
"op_in_trx": 1,
"timestamp": "2020-02-10T14:34:24",
"virtual_op": true,
"trx_in_block": 2
}2020/02/10 14:34:24
2020/02/10 14:34:24
| voter | acidsound |
| author | splex7 |
| weight | 10000 (100.00%) |
| permlink | mco |
| Transaction Info | Block #40699478/Trx 6623bff22ce1442081a70e2d025fe73f87e12fe1 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "acidsound",
"author": "splex7",
"weight": 10000,
"permlink": "mco"
}
],
"block": 40699478,
"trx_id": "6623bff22ce1442081a70e2d025fe73f87e12fe1",
"op_in_trx": 0,
"timestamp": "2020-02-10T14:34:24",
"virtual_op": false,
"trx_in_block": 2
}acidsoundupdated payout for loom-network-blockchain-explorer2019/10/10 15:03:33
acidsoundupdated payout for loom-network-blockchain-explorer
2019/10/10 15:03:33
| author | acidsound |
| permlink | loom-network-blockchain-explorer |
| Transaction Info | Block #37164508/Virtual Operation 4294967295:9 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "loom-network-blockchain-explorer"
}
],
"block": 37164508,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 9,
"timestamp": "2019-10-10T15:03:33",
"virtual_op": true,
"trx_in_block": 4294967295
}acidsoundreceived 4.560 HBD reward share for loom-network-blockchain-explorer2019/10/10 15:03:33
acidsoundreceived 4.560 HBD reward share for loom-network-blockchain-explorer
2019/10/10 15:03:33
| author | acidsound |
| payout | 4.560 HBD |
| permlink | loom-network-blockchain-explorer |
| author rewards | 11101 |
| total payout value | 2.280 HBD |
| curator payout value | 2.280 HBD |
| beneficiary payout value | 0.000 HBD |
| Transaction Info | Block #37164508/Virtual Operation 4294967295:8 |
View Raw JSON Data
{
"op": [
"comment_reward",
{
"author": "acidsound",
"payout": "4.560 HBD",
"permlink": "loom-network-blockchain-explorer",
"author_rewards": 11101,
"total_payout_value": "2.280 HBD",
"curator_payout_value": "2.280 HBD",
"beneficiary_payout_value": "0.000 HBD"
}
],
"block": 37164508,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 8,
"timestamp": "2019-10-10T15:03:33",
"virtual_op": true,
"trx_in_block": 4294967295
}acidsoundreceived 5.550 HIVE, 6.761 HP author reward for @acidsound / loom-network-blockchain-explorer2019/10/10 15:03:33
acidsoundreceived 5.550 HIVE, 6.761 HP author reward for @acidsound / loom-network-blockchain-explorer
2019/10/10 15:03:33
| author | acidsound |
| permlink | loom-network-blockchain-explorer |
| hbd payout | 0.000 HBD |
| hive payout | 5.550 HIVE |
| vesting payout | 10974.934140 VESTS |
| payout must be claimed | true |
| curators vesting payout | 21943.936952 VESTS |
| Transaction Info | Block #37164508/Virtual Operation 4294967295:7 |
View Raw JSON Data
{
"op": [
"author_reward",
{
"author": "acidsound",
"permlink": "loom-network-blockchain-explorer",
"hbd_payout": "0.000 HBD",
"hive_payout": "5.550 HIVE",
"vesting_payout": "10974.934140 VESTS",
"payout_must_be_claimed": true,
"curators_vesting_payout": "21943.936952 VESTS"
}
],
"block": 37164508,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 7,
"timestamp": "2019-10-10T15:03:33",
"virtual_op": true,
"trx_in_block": 4294967295
}acidsoundreceived 0.001 HP curation reward for @acidsound / loom-network-blockchain-explorer2019/10/10 15:03:33
acidsoundreceived 0.001 HP curation reward for @acidsound / loom-network-blockchain-explorer
2019/10/10 15:03:33
| author | acidsound |
| reward | 1.977109 VESTS |
| curator | acidsound |
| permlink | loom-network-blockchain-explorer |
| payout must be claimed | true |
| Transaction Info | Block #37164508/Virtual Operation 4294967295:6 |
View Raw JSON Data
{
"op": [
"curation_reward",
{
"author": "acidsound",
"reward": "1.977109 VESTS",
"curator": "acidsound",
"permlink": "loom-network-blockchain-explorer",
"payout_must_be_claimed": true
}
],
"block": 37164508,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 6,
"timestamp": "2019-10-10T15:03:33",
"virtual_op": true,
"trx_in_block": 4294967295
}acidsoundupdated payout for libp2p-2-node2019/10/10 14:57:57
acidsoundupdated payout for libp2p-2-node
2019/10/10 14:57:57
| author | acidsound |
| permlink | libp2p-2-node |
| Transaction Info | Block #37164396/Virtual Operation 4294967295:115 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "libp2p-2-node"
}
],
"block": 37164396,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 115,
"timestamp": "2019-10-10T14:57:57",
"virtual_op": true,
"trx_in_block": 4294967295
}acidsoundremoved vote from (0.00%) @acidsound / msgib9g7t542019/10/07 14:20:48
acidsoundremoved vote from (0.00%) @acidsound / msgib9g7t54
2019/10/07 14:20:48
| voter | acidsound |
| author | acidsound |
| weight | 0 (0.00%) |
| permlink | msgib9g7t54 |
| Transaction Info | Block #37077431/Trx 67ea4a26536f8e783f31008b07ee6d94ac14dc84 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "acidsound",
"author": "acidsound",
"weight": 0,
"permlink": "msgib9g7t54"
}
],
"block": 37077431,
"trx_id": "67ea4a26536f8e783f31008b07ee6d94ac14dc84",
"op_in_trx": 0,
"timestamp": "2019-10-07T14:20:48",
"virtual_op": false,
"trx_in_block": 0
}acidsoundupdated payout for msgib9g7t542019/10/05 09:26:12
acidsoundupdated payout for msgib9g7t54
2019/10/05 09:26:12
| author | acidsound |
| permlink | msgib9g7t54 |
| Transaction Info | Block #37014063/Virtual Operation 4294967295:2 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "msgib9g7t54"
}
],
"block": 37014063,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 2,
"timestamp": "2019-10-05T09:26:12",
"virtual_op": true,
"trx_in_block": 4294967295
}acidsoundupdated payout for v101a59uobd2019/10/05 08:29:36
acidsoundupdated payout for v101a59uobd
2019/10/05 08:29:36
| author | acidsound |
| permlink | v101a59uobd |
| Transaction Info | Block #37012932/Virtual Operation 4294967295:2 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "v101a59uobd"
}
],
"block": 37012932,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 2,
"timestamp": "2019-10-05T08:29:36",
"virtual_op": true,
"trx_in_block": 4294967295
}happybellyeffective vote applied for @acidsound / loom-network-blockchain-explorer2019/10/03 23:15:21
happybellyeffective vote applied for @acidsound / loom-network-blockchain-explorer
2019/10/03 23:15:21
| voter | happybelly |
| author | acidsound |
| weight | 553080 |
| rshares | 3628842147587 |
| permlink | loom-network-blockchain-explorer |
| pending payout | 4.887 HBD |
| total vote weight | 3403718 |
| Transaction Info | Block #36973129/Trx 676779beda6c7b441025af00a4182ee487394b27 |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "happybelly",
"author": "acidsound",
"weight": 553080,
"rshares": 3628842147587,
"permlink": "loom-network-blockchain-explorer",
"pending_payout": "4.887 HBD",
"total_vote_weight": 3403718
}
],
"block": 36973129,
"trx_id": "676779beda6c7b441025af00a4182ee487394b27",
"op_in_trx": 1,
"timestamp": "2019-10-03T23:15:21",
"virtual_op": true,
"trx_in_block": 17
}happybellyupvoted (10.00%) @acidsound / loom-network-blockchain-explorer2019/10/03 23:15:21
happybellyupvoted (10.00%) @acidsound / loom-network-blockchain-explorer
2019/10/03 23:15:21
| voter | happybelly |
| author | acidsound |
| weight | 1000 (10.00%) |
| permlink | loom-network-blockchain-explorer |
| Transaction Info | Block #36973129/Trx 676779beda6c7b441025af00a4182ee487394b27 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "happybelly",
"author": "acidsound",
"weight": 1000,
"permlink": "loom-network-blockchain-explorer"
}
],
"block": 36973129,
"trx_id": "676779beda6c7b441025af00a4182ee487394b27",
"op_in_trx": 0,
"timestamp": "2019-10-03T23:15:21",
"virtual_op": false,
"trx_in_block": 17
}seapyeffective vote applied for @acidsound / loom-network-blockchain-explorer2019/10/03 19:48:15
seapyeffective vote applied for @acidsound / loom-network-blockchain-explorer
2019/10/03 19:48:15
| voter | seapy |
| author | acidsound |
| weight | 655 (6.55%) |
| rshares | 3866297211 |
| permlink | loom-network-blockchain-explorer |
| pending payout | 3.541 HBD |
| total vote weight | 2850638 |
| Transaction Info | Block #36968995/Trx e860f944e542ac42bd60e0ba67ada1ae2eb23bb0 |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "seapy",
"author": "acidsound",
"weight": 655,
"rshares": 3866297211,
"permlink": "loom-network-blockchain-explorer",
"pending_payout": "3.541 HBD",
"total_vote_weight": 2850638
}
],
"block": 36968995,
"trx_id": "e860f944e542ac42bd60e0ba67ada1ae2eb23bb0",
"op_in_trx": 1,
"timestamp": "2019-10-03T19:48:15",
"virtual_op": true,
"trx_in_block": 16
}seapyupvoted (60.00%) @acidsound / loom-network-blockchain-explorer2019/10/03 19:48:15
seapyupvoted (60.00%) @acidsound / loom-network-blockchain-explorer
2019/10/03 19:48:15
| voter | seapy |
| author | acidsound |
| weight | 6000 (60.00%) |
| permlink | loom-network-blockchain-explorer |
| Transaction Info | Block #36968995/Trx e860f944e542ac42bd60e0ba67ada1ae2eb23bb0 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "seapy",
"author": "acidsound",
"weight": 6000,
"permlink": "loom-network-blockchain-explorer"
}
],
"block": 36968995,
"trx_id": "e860f944e542ac42bd60e0ba67ada1ae2eb23bb0",
"op_in_trx": 0,
"timestamp": "2019-10-03T19:48:15",
"virtual_op": false,
"trx_in_block": 16
}haejineffective vote applied for @acidsound / loom-network-blockchain-explorer2019/10/03 19:41:30
haejineffective vote applied for @acidsound / loom-network-blockchain-explorer
2019/10/03 19:41:30
| voter | haejin |
| author | acidsound |
| weight | 2849631 |
| rshares | 11109881694973 |
| permlink | loom-network-blockchain-explorer |
| pending payout | 3.541 HBD |
| total vote weight | 2849983 |
| Transaction Info | Block #36968860/Trx 0668674ed8a7049c840f9d2b642f3624d1a6e40a |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "haejin",
"author": "acidsound",
"weight": 2849631,
"rshares": 11109881694973,
"permlink": "loom-network-blockchain-explorer",
"pending_payout": "3.541 HBD",
"total_vote_weight": 2849983
}
],
"block": 36968860,
"trx_id": "0668674ed8a7049c840f9d2b642f3624d1a6e40a",
"op_in_trx": 1,
"timestamp": "2019-10-03T19:41:30",
"virtual_op": true,
"trx_in_block": 0
}haejinupvoted (100.00%) @acidsound / loom-network-blockchain-explorer2019/10/03 19:41:30
haejinupvoted (100.00%) @acidsound / loom-network-blockchain-explorer
2019/10/03 19:41:30
| voter | haejin |
| author | acidsound |
| weight | 10000 (100.00%) |
| permlink | loom-network-blockchain-explorer |
| Transaction Info | Block #36968860/Trx 0668674ed8a7049c840f9d2b642f3624d1a6e40a |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "haejin",
"author": "acidsound",
"weight": 10000,
"permlink": "loom-network-blockchain-explorer"
}
],
"block": 36968860,
"trx_id": "0668674ed8a7049c840f9d2b642f3624d1a6e40a",
"op_in_trx": 0,
"timestamp": "2019-10-03T19:41:30",
"virtual_op": false,
"trx_in_block": 0
}seapyeffective vote applied for @acidsound / libp2p-2-node2019/10/03 19:18:15
seapyeffective vote applied for @acidsound / libp2p-2-node
2019/10/03 19:18:15
| voter | seapy |
| author | acidsound |
| weight | 1936 (19.36%) |
| rshares | 3878858103 |
| permlink | libp2p-2-node |
| pending payout | 0.000 HBD |
| total vote weight | 1936 |
| Transaction Info | Block #36968396/Trx c1dff19f2ff9ddf44c7b39efa78138a3608d0ff7 |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "seapy",
"author": "acidsound",
"weight": 1936,
"rshares": 3878858103,
"permlink": "libp2p-2-node",
"pending_payout": "0.000 HBD",
"total_vote_weight": 1936
}
],
"block": 36968396,
"trx_id": "c1dff19f2ff9ddf44c7b39efa78138a3608d0ff7",
"op_in_trx": 1,
"timestamp": "2019-10-03T19:18:15",
"virtual_op": true,
"trx_in_block": 7
}seapyupvoted (60.00%) @acidsound / libp2p-2-node2019/10/03 19:18:15
seapyupvoted (60.00%) @acidsound / libp2p-2-node
2019/10/03 19:18:15
| voter | seapy |
| author | acidsound |
| weight | 6000 (60.00%) |
| permlink | libp2p-2-node |
| Transaction Info | Block #36968396/Trx c1dff19f2ff9ddf44c7b39efa78138a3608d0ff7 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "seapy",
"author": "acidsound",
"weight": 6000,
"permlink": "libp2p-2-node"
}
],
"block": 36968396,
"trx_id": "c1dff19f2ff9ddf44c7b39efa78138a3608d0ff7",
"op_in_trx": 0,
"timestamp": "2019-10-03T19:18:15",
"virtual_op": false,
"trx_in_block": 7
}acidsoundeffective vote applied for @acidsound / loom-network-blockchain-explorer2019/10/03 15:22:51
acidsoundeffective vote applied for @acidsound / loom-network-blockchain-explorer
2019/10/03 15:22:51
| voter | acidsound |
| author | acidsound |
| weight | 352 (3.52%) |
| rshares | 705804226 |
| permlink | loom-network-blockchain-explorer |
| pending payout | 0.000 HBD |
| total vote weight | 352 |
| Transaction Info | Block #36963696/Trx 3d2abdcb33cbcacd67a9f24a112d506d5a1f2b8e |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "acidsound",
"author": "acidsound",
"weight": 352,
"rshares": 705804226,
"permlink": "loom-network-blockchain-explorer",
"pending_payout": "0.000 HBD",
"total_vote_weight": 352
}
],
"block": 36963696,
"trx_id": "3d2abdcb33cbcacd67a9f24a112d506d5a1f2b8e",
"op_in_trx": 1,
"timestamp": "2019-10-03T15:22:51",
"virtual_op": true,
"trx_in_block": 34
}acidsoundupvoted (100.00%) @acidsound / loom-network-blockchain-explorer2019/10/03 15:22:51
acidsoundupvoted (100.00%) @acidsound / loom-network-blockchain-explorer
2019/10/03 15:22:51
| voter | acidsound |
| author | acidsound |
| weight | 10000 (100.00%) |
| permlink | loom-network-blockchain-explorer |
| Transaction Info | Block #36963696/Trx 3d2abdcb33cbcacd67a9f24a112d506d5a1f2b8e |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "acidsound",
"author": "acidsound",
"weight": 10000,
"permlink": "loom-network-blockchain-explorer"
}
],
"block": 36963696,
"trx_id": "3d2abdcb33cbcacd67a9f24a112d506d5a1f2b8e",
"op_in_trx": 0,
"timestamp": "2019-10-03T15:22:51",
"virtual_op": false,
"trx_in_block": 34
}acidsoundpublished a new post: loom-network-blockchain-explorer2019/10/03 15:06:45
acidsoundpublished a new post: loom-network-blockchain-explorer
2019/10/03 15:06:45
| body | @@ -8604,16 +8604,184 @@ %EB%A0%A4%EB%82%98 %EB%AA%A8%EB%A5%B4%EA%B2%A0%EB%8B%A4. +%0A%EB%8B%A4%EC%8B%9C %EB%B3%B4%EB%82%B4%EB%A9%B4%EC%84%9C %EB%AA%A8%EB%B0%94%EC%9D%BC %EB%8C%80%EC%9D%91%EB%8F%84 %EC%A2%80 %EC%8B%A0%EA%B2%BD%EC%9D%84 %EC%8D%BC%EB%8B%A4.%0A!%5Bscreenshot%5D(https://cdn.steemitimages.com/DQmUgy2doBjsoBP2HY9PwfquBudUhuCc1LDh9ufki3Rwfds/image.png)%0A%ED%95%98%EB%8B%A4%EB%B3%B4%EB%8B%88 %EC%9A%94%EB%9F%B0 %EB%AA%A8%EC%96%91%EC%9D%B4 %EB%82%98%EC%99%94%EB%8B%A4. (%EB%A3%A9%EC%9D%84 %EC%86%90%EB%B4%90%EC%A4%80 splex7 %EA%BB%98 %EA%B0%90%EC%82%AC!) %0A%0A%EC%95%84%EC%A7%81 %ED%95%B4%EC%95%BC%ED%95%A0 |
| title | loom network의 blockchain explorer를 만들어 보자. |
| author | acidsound |
| permlink | loom-network-blockchain-explorer |
| json metadata | {"tags":["kr","loom"],"links":["https://loomx.io/developers/en/block-explorer-tutorial.html#overview","https://plasma.dappchains.com/rpc/blockchain?minHeight=12668090&maxHeight=12668099","https://plasma.dappchains.com/rpc/status","https://plasma.dappchains.com/rpc","https://codepen.io/acidsound/pen/qBWGxpR","https://plasma.dappchains.com/rpc/tx?hash=0x4FADC98AB71EEC1E71384C5286B761B9AC58A6C1647C7DFF0886B8243BB9B062"],"app":"steemit/0.1","format":"markdown","image":["https://cdn.steemitimages.com/DQmUgy2doBjsoBP2HY9PwfquBudUhuCc1LDh9ufki3Rwfds/image.png"]} |
| parent author | |
| parent permlink | kr-dev |
| Transaction Info | Block #36963375/Trx 8be6b516a154cebdf215e863c4419dec7890f676 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "@@ -8604,16 +8604,184 @@\n %EB%A0%A4%EB%82%98 %EB%AA%A8%EB%A5%B4%EA%B2%A0%EB%8B%A4.\n+%0A%EB%8B%A4%EC%8B%9C %EB%B3%B4%EB%82%B4%EB%A9%B4%EC%84%9C %EB%AA%A8%EB%B0%94%EC%9D%BC %EB%8C%80%EC%9D%91%EB%8F%84 %EC%A2%80 %EC%8B%A0%EA%B2%BD%EC%9D%84 %EC%8D%BC%EB%8B%A4.%0A!%5Bscreenshot%5D(https://cdn.steemitimages.com/DQmUgy2doBjsoBP2HY9PwfquBudUhuCc1LDh9ufki3Rwfds/image.png)%0A%ED%95%98%EB%8B%A4%EB%B3%B4%EB%8B%88 %EC%9A%94%EB%9F%B0 %EB%AA%A8%EC%96%91%EC%9D%B4 %EB%82%98%EC%99%94%EB%8B%A4. (%EB%A3%A9%EC%9D%84 %EC%86%90%EB%B4%90%EC%A4%80 splex7 %EA%BB%98 %EA%B0%90%EC%82%AC!)\n %0A%0A%EC%95%84%EC%A7%81 %ED%95%B4%EC%95%BC%ED%95%A0\n",
"title": "loom network의 blockchain explorer를 만들어 보자.",
"author": "acidsound",
"permlink": "loom-network-blockchain-explorer",
"json_metadata": "{\"tags\":[\"kr\",\"loom\"],\"links\":[\"https://loomx.io/developers/en/block-explorer-tutorial.html#overview\",\"https://plasma.dappchains.com/rpc/blockchain?minHeight=12668090&maxHeight=12668099\",\"https://plasma.dappchains.com/rpc/status\",\"https://plasma.dappchains.com/rpc\",\"https://codepen.io/acidsound/pen/qBWGxpR\",\"https://plasma.dappchains.com/rpc/tx?hash=0x4FADC98AB71EEC1E71384C5286B761B9AC58A6C1647C7DFF0886B8243BB9B062\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\",\"image\":[\"https://cdn.steemitimages.com/DQmUgy2doBjsoBP2HY9PwfquBudUhuCc1LDh9ufki3Rwfds/image.png\"]}",
"parent_author": "",
"parent_permlink": "kr-dev"
}
],
"block": 36963375,
"trx_id": "8be6b516a154cebdf215e863c4419dec7890f676",
"op_in_trx": 0,
"timestamp": "2019-10-03T15:06:45",
"virtual_op": false,
"trx_in_block": 4
}acidsoundpublished a new post: loom-network-blockchain-explorer2019/10/03 15:03:36
acidsoundpublished a new post: loom-network-blockchain-explorer
2019/10/03 15:03:36
| body | 한동안 guns.db와 함께 관심갖고 보았던 loom에서 event를 하고 있는데 재미있어보여 블록 탐색기부터 시도해보기로 한다. https://loomx.io/developers/en/block-explorer-tutorial.html#overview 튜토리얼이 있긴 한데 말이 튜토리얼이지 github 소스하나 툭 던지고 뭐 없다. 성격도 급하고 일단 빨랑 제출해야 되니까 github 소스 받아서 실행하고 chrome 의 network tab 을 열었다. Request URL: https://plasma.dappchains.com/rpc/blockchain?minHeight=12668090&maxHeight=12668099 요런거랑 Request URL: https://plasma.dappchains.com/rpc/status 요런거 두개 가 보였다. 더 뭔가 없을까 해서 이것저것 처보다가. https://plasma.dappchains.com/rpc 여기를 보니 사용가능한 endpoints 들이 쭉 나온다. Available endpoints: //plasma.dappchains.com/abci_info //plasma.dappchains.com/consensus_state //plasma.dappchains.com/dump_consensus_state //plasma.dappchains.com/genesis //plasma.dappchains.com/health //plasma.dappchains.com/net_info //plasma.dappchains.com/num_unconfirmed_txs //plasma.dappchains.com/status Endpoints that require arguments: //plasma.dappchains.com/abci_query?path=_&data=_&height=_&prove=_ //plasma.dappchains.com/block?height=_ //plasma.dappchains.com/block_results?height=_ //plasma.dappchains.com/blockchain?minHeight=_&maxHeight=_ //plasma.dappchains.com/broadcast_tx_async?tx=_ //plasma.dappchains.com/broadcast_tx_commit?tx=_ //plasma.dappchains.com/broadcast_tx_sync?tx=_ //plasma.dappchains.com/commit?height=_ //plasma.dappchains.com/consensus_params?height=_ //plasma.dappchains.com/mempool_txs?limit=_ //plasma.dappchains.com/nonce?key=_&account=_ //plasma.dappchains.com/subscribe?query=_ //plasma.dappchains.com/tx?hash=_&prove=_ //plasma.dappchains.com/tx_search?query=_&prove=_&page=_&per_page=_ //plasma.dappchains.com/unconfirmed_txs?limit=_ //plasma.dappchains.com/unsubscribe?query=_ //plasma.dappchains.com/unsubscribe_all? //plasma.dappchains.com/validators?height=_ 뭐 이정도면 충분하지 않을까 싶어 바로 착수. codepen.io에 대충 반들어보니까 https://codepen.io/acidsound/pen/qBWGxpR 생각보다 어렵지 않게 되었다. 필요한건 뭐? 스피드! 언제나 좋아하는 황금조합인 parcel+github+netlify 로 외부 노출 주소, https 설정, CI까지 한번에 3분만에 완료. package.json을 아래와 같이 만들고 코딩을 시작해본다. { "name": "loomxplorer", "version": "1.0.0", "main": "index.html", "scripts": { "build": "parcel build index.pug" }, "license": "MIT", "devDependencies": { "cssnano": "^4.1.10", "parcel": "^1.12.3", "pug": "^2.0.4", "stylus": "^0.54.7" }, "dependencies": { "date-fns": "^2.4.1" } } scripts 에 build 를 넣는게 포인트. build script 를 실행하면 dist 디렉토리에 떨어뜨려준다. netlify에서 build & deploy > Continuous Deployment에 아래와 같이 되도록 설정한다. npm run build 와 /dist정도만 잘 쓰면 문제 없다. Build settings Repository: github.com/acidsound/loomXplorer Base directory: Not set Build command: npm run build Publish directory: /dist Deploy log visibility: Logs are public RPC API 중에 쓸만한 걸 꼽아보니. //plasma.dappchains.com/rpc/status (상태) //plasma.dappchains.com/rpc/block?height=_ (특정블록의 정보) //plasma.dappchains.com/rpc/block_results?height=_ (블록결과) //plasma.dappchains.com/rpc/blockchain?minHeight=_&maxHeight=_ (블록하이트 범위 지정 쿼리) 정도? 일단 js 부터. import 해줄게 뭐가 있지? import 'regenerator-runtime/runtime' import { formatDistance } from 'date-fns' 일단 async/await을 쓸테니까 'regenerator-runtime/runtime'하고 시간도 보여줄꺼니까 무거운 moment대신 date-fns를 써서 formatDistance를 가져다 놓자. API들 먼저 정의해놓자. const cmds = { "endpoint": "https://plasma.dappchains.com/rpc", "status": "/status", "blockheight": "/blockchain?", "block": "/block?height=", "tx": "/tx?hash=", } 요정도면 충분. fetch를 조금 개조해서 json에 result만 가져오는 걸 하나 만들자. const afetch = async (url, options={})=> (await (await fetch(url, options)).json()).result 닭질이 많이 줄어든다. 이걸로 현재 status랑 min~maxHeight 까지 목록 조회하는 걸 만들어본다. status는 마지막 blockHeight를 가져오기 위한 용도이면 min은 이 blockHeight-9로 설정하려고 한다. const getChainStatus = async ()=> await afetch(`${cmds.endpoint}${cmds.status}`) const getBlocks = async ({from, to})=> await afetch(`${cmds.endpoint}${cmds.blockheight}minHeight=${from}&maxHeight=${to}`) 아주 아주 간단하다. 보니까 시간이 ISOTime 형식으로 나오는데 현재 시간으로부터 얼마나 지났는지 알려주는 함수도 하나 만들자. const getSinceFrom = since => formatDistance(Date.parse(since), new Date()) react나 vue같은 걸 써서 이쁘게 해도 되겠지만 시간이 없으니까 빠르게 DOM을 생성하는 걸 만들어서 집어넣자. ul#blocks__meta li.row.hash.obj .head .desc .transaction span span | transactions .validator span.highlightedText | Validator span.link .since 목록이 되는 리스트인데 pug가 익숙하지 않은 분들을 위해 html로 쓰면 <ul id="blocks__meta"> <li class="row hash obj"> <div class="head"> </div> <div class="desc"> <div class="transaction"><span></span><span>transactions</span></div> <div class="validator"><span class="highlightedText"> Validator</span><span class="link"></span></div> <div class="since"></div> </div> </li> </ul> 이렇게 작성했다. html보단 pug를, css보단 stylus를, js보단 coffeescript(이번엔 js로 했다)를 코드 양이 적어서 선호하는 편인데 .obj 라는 클래스를 일단 만들어넣고 얘는 display: none 으로 안보이게 한 뒤 deep copy해서 쓰는 식으로 목록을 생성하게 했다. 일정 주기마다 blockheight를 받아오는 API를 호출하고 받아온 값을 가지고 렌더링하는 함수를 만든다. const updateHashLists = ({blockMetas})=> { const list = document.querySelector("#blocks__meta") const lastBlockheightElement = document.querySelector("#blocks__meta>.row.hash.item") const lastBlockheight = lastBlockheightElement && lastBlockheightElement.getAttribute('data-id') || 0 blockMetas = blockMetas.filter(o=>o.header.height>lastBlockheight) blockMetas.reverse().forEach(v=>{ const node = document.querySelector("#blocks__meta .hash.obj").cloneNode({deep: true}); node.classList.remove("obj") node.classList.add("item") node.setAttribute("data-id", v.header.height) node.setAttribute('data-hash', v.header.data_hash) node.querySelector('.head').textContent = "#"+v.header.height node.querySelector('.desc>.transaction>span').textContent = v.header.num_txs node.querySelector('.desc>.validator>.link').textContent = `loom${v.header.proposer_address}` const since = node.querySelector('.desc>.since') since.textContent = getSinceFrom(v.header.time) since.setAttribute('data-since', v.header.time) node.addEventListener("click", onBlockClickHandler) list.prepend(node) }) document.querySelectorAll("#blocks__meta .item").forEach((o,k)=>{ k>pageCnt && o.remove() }) } node.addEventListener("click", onBlockClickHandler) 클릭이벤트를 받을 수 있게 Handler도 붙인다. const onBlockClickHandler = async e => { const t = e.currentTarget const dataId = t.getAttribute('data-id') let tx = await aFetch(`${APIs.endpoint}${APIs.tx}0x${t.getAttribute('data-hash')}`) document.querySelector("#blockDetail").classList.remove("chosen") document.querySelector("#blockDetail").classList.add("chosen") document.querySelector("#blockDetail .blockHeight").textContent = "#" + dataId if (!tx) { tx = { hash: "", tx_result: { info: "", data: "", } } } document.querySelector("#blockDetail .txDetail>.hash>.hash").textContent = tx.hash document.querySelector("#blockDetail .txDetail>.result>.info").textContent = tx.tx_result.info document.querySelector("#blockDetail .txDetail>.result>.data").textContent = tx.tx_result.data } 내용은 뭘 보여줄까 하다가 tx 내용을 보여주기로 했다. rpc 목록에 있는 tx 항목에 맞게 https://plasma.dappchains.com/rpc/tx?hash=0x4FADC98AB71EEC1E71384C5286B761B9AC58A6C1647C7DFF0886B8243BB9B062 이런 식으로 요청하면 { "jsonrpc": "2.0", "id": "", "result": { "hash": "4FADC98AB71EEC1E71384C5286B761B9AC58A6C1647C7DFF0886B8243BB9B062", "height": "12841608", "index": 0, "tx_result": { "data": "Y4urfueVKwei0sWkswDDa8rICBd7fxxYUnimqj+1Zc8=", "info": "call.evm" }, "tx": "ClsKVQgCElEKHwoHZGVmYXVsdBIUN1z+jN0iOvY2Yn9d3FmDht9zGkgSHwoHZGVmYXVsdBIUE5/Vz/WpnsQdMteVf2mWradVFxsaDQgBEgTe4RywGgMKAQAQ4KgEEkBO+30aq9YnK5dYEblZTo99TeDts53CQTahXm13Bxtg/BTyV+2fkZfC+hZusSuvgseO3S8hYfxQK9MAIcsex6wKGiCNeP1V3ZNXYw9Wib2fQ11XtB26/wa6wD7ByRBaXLlhfg==" } } tx의 종류와 데이터가 나온다. 여기까지하고 일단 제출. 모집 글에 메일 주소 오타가 있어 두번 보냈는데 제대로 갔으려나 모르겠다. 아직 해야할 것이 많은데 피드백 보고 계속할지 생각해봐야겠다. 소스 저장소는 이쪽. 포크, 풀리퀘 모두 환영합니다. |
| title | loom network의 blockchain explorer를 만들어 보자. |
| author | acidsound |
| permlink | loom-network-blockchain-explorer |
| json metadata | {"tags":["kr-dev","kr","loom"],"links":["https://loomx.io/developers/en/block-explorer-tutorial.html#overview","https://plasma.dappchains.com/rpc/blockchain?minHeight=12668090&maxHeight=12668099","https://plasma.dappchains.com/rpc/status","https://plasma.dappchains.com/rpc","https://codepen.io/acidsound/pen/qBWGxpR","https://plasma.dappchains.com/rpc/tx?hash=0x4FADC98AB71EEC1E71384C5286B761B9AC58A6C1647C7DFF0886B8243BB9B062"],"app":"steemit/0.1","format":"markdown"} |
| parent author | |
| parent permlink | kr-dev |
| Transaction Info | Block #36963313/Trx d1dbcff099e03b7ce1cddd618c3e9299041cf591 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "한동안 guns.db와 함께 관심갖고 보았던 loom에서 event를 하고 있는데 재미있어보여 블록 탐색기부터 시도해보기로 한다.\n\nhttps://loomx.io/developers/en/block-explorer-tutorial.html#overview\n\n튜토리얼이 있긴 한데 말이 튜토리얼이지 github 소스하나 툭 던지고 뭐 없다.\n\n성격도 급하고 일단 빨랑 제출해야 되니까 github 소스 받아서 실행하고 chrome 의 network tab 을 열었다.\n\nRequest URL: https://plasma.dappchains.com/rpc/blockchain?minHeight=12668090&maxHeight=12668099\n\n요런거랑 \nRequest URL: https://plasma.dappchains.com/rpc/status\n\n요런거 두개 가 보였다. 더 뭔가 없을까 해서 이것저것 처보다가.\n\nhttps://plasma.dappchains.com/rpc 여기를 보니 \n\n사용가능한 endpoints 들이 쭉 나온다.\n\n Available endpoints:\n //plasma.dappchains.com/abci_info\n //plasma.dappchains.com/consensus_state\n //plasma.dappchains.com/dump_consensus_state\n //plasma.dappchains.com/genesis\n //plasma.dappchains.com/health\n //plasma.dappchains.com/net_info\n //plasma.dappchains.com/num_unconfirmed_txs\n //plasma.dappchains.com/status\n \n Endpoints that require arguments:\n //plasma.dappchains.com/abci_query?path=_&data=_&height=_&prove=_\n //plasma.dappchains.com/block?height=_\n //plasma.dappchains.com/block_results?height=_\n //plasma.dappchains.com/blockchain?minHeight=_&maxHeight=_\n //plasma.dappchains.com/broadcast_tx_async?tx=_\n //plasma.dappchains.com/broadcast_tx_commit?tx=_\n //plasma.dappchains.com/broadcast_tx_sync?tx=_\n //plasma.dappchains.com/commit?height=_\n //plasma.dappchains.com/consensus_params?height=_\n //plasma.dappchains.com/mempool_txs?limit=_\n //plasma.dappchains.com/nonce?key=_&account=_\n //plasma.dappchains.com/subscribe?query=_\n //plasma.dappchains.com/tx?hash=_&prove=_\n //plasma.dappchains.com/tx_search?query=_&prove=_&page=_&per_page=_\n //plasma.dappchains.com/unconfirmed_txs?limit=_\n //plasma.dappchains.com/unsubscribe?query=_\n //plasma.dappchains.com/unsubscribe_all?\n //plasma.dappchains.com/validators?height=_\n\n뭐 이정도면 충분하지 않을까 싶어 바로 착수.\n\ncodepen.io에 대충 반들어보니까\n\nhttps://codepen.io/acidsound/pen/qBWGxpR\n\n생각보다 어렵지 않게 되었다.\n\n필요한건 뭐? 스피드!\n\n언제나 좋아하는 황금조합인\n\nparcel+github+netlify 로 외부 노출 주소, https 설정, CI까지 한번에 3분만에 완료.\n\npackage.json을 아래와 같이 만들고 코딩을 시작해본다.\n\n {\n \"name\": \"loomxplorer\",\n \"version\": \"1.0.0\",\n \"main\": \"index.html\",\n \"scripts\": {\n \"build\": \"parcel build index.pug\"\n },\n \"license\": \"MIT\",\n \"devDependencies\": {\n \"cssnano\": \"^4.1.10\",\n \"parcel\": \"^1.12.3\",\n \"pug\": \"^2.0.4\",\n \"stylus\": \"^0.54.7\"\n },\n \"dependencies\": {\n \"date-fns\": \"^2.4.1\"\n }\n }\n\nscripts 에 build 를 넣는게 포인트. build script 를 실행하면 dist 디렉토리에 떨어뜨려준다.\n\nnetlify에서 build & deploy > Continuous Deployment에 아래와 같이 되도록 설정한다. npm run build 와 /dist정도만 잘 쓰면 문제 없다.\n\n Build settings\n Repository: github.com/acidsound/loomXplorer\n Base directory: Not set\n Build command: npm run build\n Publish directory: /dist\n Deploy log visibility: Logs are public\n\nRPC API 중에 쓸만한 걸 꼽아보니.\n\n //plasma.dappchains.com/rpc/status (상태)\n //plasma.dappchains.com/rpc/block?height=_ (특정블록의 정보)\n //plasma.dappchains.com/rpc/block_results?height=_ (블록결과)\n //plasma.dappchains.com/rpc/blockchain?minHeight=_&maxHeight=_ (블록하이트 범위 지정 쿼리)\n\n정도?\n\n일단 js 부터.\n\nimport 해줄게 뭐가 있지?\n\n import 'regenerator-runtime/runtime'\n import { formatDistance } from 'date-fns'\n\n일단 async/await을 쓸테니까 'regenerator-runtime/runtime'하고 시간도 보여줄꺼니까 무거운 moment대신 date-fns를 써서 formatDistance를 가져다 놓자.\n\nAPI들 먼저 정의해놓자.\n\n const cmds = {\n \"endpoint\": \"https://plasma.dappchains.com/rpc\",\n \"status\": \"/status\",\n \"blockheight\": \"/blockchain?\",\n \"block\": \"/block?height=\",\n \"tx\": \"/tx?hash=\",\n }\n\n요정도면 충분.\n\nfetch를 조금 개조해서 json에 result만 가져오는 걸 하나 만들자.\n\n const afetch = async (url, options={})=>\n (await (await fetch(url, options)).json()).result\n\n닭질이 많이 줄어든다.\n\n이걸로 현재 status랑 min~maxHeight 까지 목록 조회하는 걸 만들어본다. status는 마지막 blockHeight를 가져오기 위한 용도이면 min은 이 blockHeight-9로 설정하려고 한다.\n\n const getChainStatus = async ()=>\n await afetch(`${cmds.endpoint}${cmds.status}`)\n const getBlocks = async ({from, to})=>\n await afetch(`${cmds.endpoint}${cmds.blockheight}minHeight=${from}&maxHeight=${to}`)\n\n아주 아주 간단하다.\n\n보니까 시간이 ISOTime 형식으로 나오는데 현재 시간으로부터 얼마나 지났는지 알려주는 함수도 하나 만들자.\n\n const getSinceFrom = since => formatDistance(Date.parse(since), new Date())\n\nreact나 vue같은 걸 써서 이쁘게 해도 되겠지만 시간이 없으니까 빠르게 DOM을 생성하는 걸 만들어서 집어넣자.\n\n ul#blocks__meta\n li.row.hash.obj\n .head \n .desc\n .transaction\n span\n span\n | transactions\n .validator\n span.highlightedText \n | Validator\n span.link\n .since\n\n목록이 되는 리스트인데 pug가 익숙하지 않은 분들을 위해 html로 쓰면\n\n <ul id=\"blocks__meta\">\n <li class=\"row hash obj\">\n <div class=\"head\"> </div>\n <div class=\"desc\">\n <div class=\"transaction\"><span></span><span>transactions</span></div>\n <div class=\"validator\"><span class=\"highlightedText\"> Validator</span><span class=\"link\"></span></div>\n <div class=\"since\"></div>\n </div>\n </li>\n </ul>\n\n이렇게 작성했다.\n\nhtml보단 pug를, css보단 stylus를, js보단 coffeescript(이번엔 js로 했다)를 코드 양이 적어서 선호하는 편인데 .obj 라는 클래스를 일단 만들어넣고 얘는 display: none 으로 안보이게 한 뒤 deep copy해서 쓰는 식으로 목록을 생성하게 했다.\n\n일정 주기마다 blockheight를 받아오는 API를 호출하고 받아온 값을 가지고 렌더링하는 함수를 만든다.\n\n const updateHashLists = ({blockMetas})=> {\n const list = document.querySelector(\"#blocks__meta\")\n const lastBlockheightElement = document.querySelector(\"#blocks__meta>.row.hash.item\")\n const lastBlockheight = lastBlockheightElement && lastBlockheightElement.getAttribute('data-id') || 0\n blockMetas = blockMetas.filter(o=>o.header.height>lastBlockheight)\n blockMetas.reverse().forEach(v=>{\n const node = document.querySelector(\"#blocks__meta .hash.obj\").cloneNode({deep: true});\n node.classList.remove(\"obj\")\n node.classList.add(\"item\")\n node.setAttribute(\"data-id\", v.header.height)\n node.setAttribute('data-hash', v.header.data_hash)\n node.querySelector('.head').textContent = \"#\"+v.header.height\n node.querySelector('.desc>.transaction>span').textContent = v.header.num_txs\n node.querySelector('.desc>.validator>.link').textContent = `loom${v.header.proposer_address}`\n const since = node.querySelector('.desc>.since')\n since.textContent = getSinceFrom(v.header.time)\n since.setAttribute('data-since', v.header.time)\n node.addEventListener(\"click\", onBlockClickHandler)\n list.prepend(node)\n })\n document.querySelectorAll(\"#blocks__meta .item\").forEach((o,k)=>{\n k>pageCnt && o.remove()\n })\n }\n \n\nnode.addEventListener(\"click\", onBlockClickHandler) 클릭이벤트를 받을 수 있게 Handler도 붙인다.\n\n const onBlockClickHandler = async e => {\n const t = e.currentTarget\n const dataId = t.getAttribute('data-id')\n let tx = await aFetch(`${APIs.endpoint}${APIs.tx}0x${t.getAttribute('data-hash')}`)\n document.querySelector(\"#blockDetail\").classList.remove(\"chosen\")\n document.querySelector(\"#blockDetail\").classList.add(\"chosen\")\n document.querySelector(\"#blockDetail .blockHeight\").textContent = \"#\" + dataId\n if (!tx) {\n tx = {\n hash: \"\",\n tx_result: {\n info: \"\",\n data: \"\",\n }\n }\n }\n document.querySelector(\"#blockDetail .txDetail>.hash>.hash\").textContent = tx.hash\n document.querySelector(\"#blockDetail .txDetail>.result>.info\").textContent = tx.tx_result.info\n document.querySelector(\"#blockDetail .txDetail>.result>.data\").textContent = tx.tx_result.data\n }\n \n\n내용은 뭘 보여줄까 하다가 tx 내용을 보여주기로 했다.\n\nrpc 목록에 있는 tx 항목에 맞게 https://plasma.dappchains.com/rpc/tx?hash=0x4FADC98AB71EEC1E71384C5286B761B9AC58A6C1647C7DFF0886B8243BB9B062 이런 식으로 요청하면\n\n {\n \"jsonrpc\": \"2.0\",\n \"id\": \"\",\n \"result\": {\n \"hash\": \"4FADC98AB71EEC1E71384C5286B761B9AC58A6C1647C7DFF0886B8243BB9B062\",\n \"height\": \"12841608\",\n \"index\": 0,\n \"tx_result\": {\n \"data\": \"Y4urfueVKwei0sWkswDDa8rICBd7fxxYUnimqj+1Zc8=\",\n \"info\": \"call.evm\"\n },\n \"tx\": \"ClsKVQgCElEKHwoHZGVmYXVsdBIUN1z+jN0iOvY2Yn9d3FmDht9zGkgSHwoHZGVmYXVsdBIUE5/Vz/WpnsQdMteVf2mWradVFxsaDQgBEgTe4RywGgMKAQAQ4KgEEkBO+30aq9YnK5dYEblZTo99TeDts53CQTahXm13Bxtg/BTyV+2fkZfC+hZusSuvgseO3S8hYfxQK9MAIcsex6wKGiCNeP1V3ZNXYw9Wib2fQ11XtB26/wa6wD7ByRBaXLlhfg==\"\n }\n }\n\ntx의 종류와 데이터가 나온다.\n\n여기까지하고 일단 제출. 모집 글에 메일 주소 오타가 있어 두번 보냈는데 제대로 갔으려나 모르겠다.\n\n아직 해야할 것이 많은데 피드백 보고 계속할지 생각해봐야겠다.\n\n소스 저장소는 이쪽. 포크, 풀리퀘 모두 환영합니다.",
"title": "loom network의 blockchain explorer를 만들어 보자.",
"author": "acidsound",
"permlink": "loom-network-blockchain-explorer",
"json_metadata": "{\"tags\":[\"kr-dev\",\"kr\",\"loom\"],\"links\":[\"https://loomx.io/developers/en/block-explorer-tutorial.html#overview\",\"https://plasma.dappchains.com/rpc/blockchain?minHeight=12668090&maxHeight=12668099\",\"https://plasma.dappchains.com/rpc/status\",\"https://plasma.dappchains.com/rpc\",\"https://codepen.io/acidsound/pen/qBWGxpR\",\"https://plasma.dappchains.com/rpc/tx?hash=0x4FADC98AB71EEC1E71384C5286B761B9AC58A6C1647C7DFF0886B8243BB9B062\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
"parent_author": "",
"parent_permlink": "kr-dev"
}
],
"block": 36963313,
"trx_id": "d1dbcff099e03b7ce1cddd618c3e9299041cf591",
"op_in_trx": 0,
"timestamp": "2019-10-03T15:03:36",
"virtual_op": false,
"trx_in_block": 19
}acidsoundpublished a new post: libp2p-2-node2019/10/03 14:58:00
acidsoundpublished a new post: libp2p-2-node
2019/10/03 14:58:00
| body | 맥북 키보드 수리하느라 꽤 오랜 날을 보냈다. 여튼 두번째 글! 이제 p2p다운 걸 좀 해보자. peer to peer로 접근하고 메시지를 주고 받는 것이 이번 목표다. ## 복습 전에 만든 index.js를 다시 보자. ```javascript const Bundle = require('./bundle'); const PeerInfo = require('peer-info'); console.log("peer is creating..."); PeerInfo.create((err, peerInfo)=> { console.log("peerID is", peerInfo.id._idB58String); peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0'); const node = new Bundle({ peerInfo }); node.start(err=> { if (err) { throw err; } console.log(node.peerInfo.multiaddrs.toArray().map(o=>o.toString())); }); }); ``` ## Refactoring 실제로 PeerInfo.create를 통해 node를 생성하고 시작하는 것까지 했는데 이걸 node의 생성이란 것으로 일반화할 수 있다. 그러면 createNode라는 function을 만들고 node 자체를 가져오게 하면 어떨까? ```javascript const Bundle = require('./bundle'); const PeerInfo = require('peer-info'); console.log("peer is creating..."); const createNode = () => new Promise((resolve, reject) => { PeerInfo.create((err, peerInfo) => { peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0'); const node = new Bundle({peerInfo}); node.start(err => { if (err) { reject(err); } resolve(node); }); }); }); createNode() .then(node => console.log( node.peerInfo.multiaddrs.toArray().map(o => o.toString()) ) ); ``` 어짜피 알고 싶은 건 node니까 Promise로 받아오고 createNode.js 라는 파일로 분리해보자. ```javascript const Bundle = require('./bundle'); const PeerInfo = require('peer-info'); const createNode = ()=> new Promise((resolve, reject) => { PeerInfo.create((err, peerInfo) => { peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0'); const node = new Bundle({peerInfo}); node.start(err => err && reject(err) || resolve(node)) }); }); module.exports = createNode; ``` 이제 createNode를 require하도록 index.js를 수정하자. ```javascript const createNode = require('./createNode'); createNode() .then(node => console.log( node.peerInfo.multiaddrs.toArray().map(o => o.toString()) ) ); ``` 꽤 간단한 구조다. [그래프참조](https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggTFJcbmxpYnAycC0tPmJ1bmRsZVxubGlicDJwLXRjcC0tPmJ1bmRsZVxucGVlci1pbmZvLS0-Y3JlYXRlTm9kZVxuYnVuZGxlLS0-Y3JlYXRlTm9kZVxuY3JlYXRlTm9kZS0tPmluZGV4IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0)  ```mermaid graph LR libp2p-->bundle libp2p-tcp-->bundle peer-info-->createNode bundle-->createNode createNode-->index ``` ## Dial to Handle 그럼 이제 node간 통신을 구현해볼 차례다 peer간 통신을 protocol이라는 경로를 통해 구현해보자. 그러기 위해 handle(https://github.com/libp2p/js-libp2p#libp2phandleprotocol-handlerfunc--matchfunc) 을 통해 새로운 프로토콜에 대한 응답을 만들고 dialProtocol(https://github.com/libp2p/js-libp2p#libp2pdialprotocolpeer-protocol-callback)로 접근을 시도해본다. createNode에서 얻은 node 객체로 handle과 dialProtocol을 구현해보니 ```javascript createNode() .then(node => { node.handle('/print', (protocol, conn) => console.log('dialed successfully')); node.dialProtocol(node.peerInfo, '/print', (err, conn) => { if (err) throw err }); }); ``` 결과는 ``` Error: A node cannot dial itself ``` 란다. 스스로 node는 자신에게 dial을 할 수 없다. 그렇다면 두개의 node를 생성해서 한쪽은 handle, 한쪽은 dialProtocol을 호출하도록 구현하자. 두개의 node가 필요하므로 Promise.all로 배열을 만든 뒤 nodes 라는 배열로 받자. 전체 index.js의 구현은 다음과 같다. ```javascript const createNode = require('./createNode'); // createNode() // .then(node => { // node.handle('/print', (protocol, conn) => console.log('dialed successfully')); // node.dialProtocol(node.peerInfo, '/print', (err, conn) => { if (err) throw err }); // }); Promise.all([createNode(), createNode()]) .then(nodes => { nodes.forEach((node, idx) => console.log(idx, node.peerInfo.multiaddrs.toArray().map(o => o.toString()))); nodes[0].handle('/print', (protocol, conn) => { console.log("node1 dialed to node0 successfully"); }); nodes[1].dialProtocol(nodes[0].peerInfo, '/print', (err, conn) => { if (err) throw err; console.log('dialProtocol conn:', conn.peerInfo.id._idB58String); }); }); ``` 별거 없다. 1. nodes[1]이 dialProtocol을 /print 라는 protocol로 하고 2. nodes[0]가 handle에서 응답한 후 3. nodes[1]의 dialProtocol의 callBack을 호출한다. 실행해보자. ``` 0 [ '/ip4/127.0.0.1/tcp/60894/ipfs/QmTrs4KkyUXvjEhPKYnUhu1vUoy9e9yPpVytqnLsovNY6Y', '/ip4/192.168.0.59/tcp/60894/ipfs/QmTrs4KkyUXvjEhPKYnUhu1vUoy9e9yPpVytqnLsovNY6Y' ] 1 [ '/ip4/127.0.0.1/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz', '/ip4/192.168.0.59/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz' ] node1 dialed to node0 successfully dialProtocol conn: QmTrs4KkyUXvjEhPKYnUhu1vUoy9e9yPpVytqnLsovNY6Y ``` 예상한대로 나왔다. 여기서 흥미로운 점은 dialProtocol의 callback에서 인자로 넘어온 conn은 dialProtocol을 실행한 자신이 아니라 호출한 대상인 node라는 점이다. ## 다른 인스턴스에서 dial하기 node REPL(node)을 열고 handle과 dial을 따로 실행해보자. 터미널 두개를 열고 한쪽에는 아래와 같이 handle을 한줄 한줄 입력하고 ```javascript createNode = require('./createNode') let node; createNode.then(o => node); console.log(node.peerInfo.multiaddrs.toArray().map(o=>o.toString())); node.handle('/print', ()=>console.log('dialed')); ``` 여기까지하면 multiaddr 주소가 보일 것이다. ```json [ '/ip4/127.0.0.1/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz', '/ip4/192.168.0.59/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz' ] ``` 다른 한쪽엔 dial을 걸어보자. 두번째 ('/ip4/192.168.0.59/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz') 주소를 일단 복사를 해두자. 터미널을 하나 더 열고 dialProtocol을 해보자. ```javascript createNode = require('./createNode'); let node; createNode.then(o => node); node.dialProtocol('/ip4/192.168.0.59/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz', '/print', ()=>console.log(err, "")) ``` 문제가 없다면 첫번째 handle 을 하고 있던 터미널 창에 ```dialed```라고 반응할 것이다. 지금쯤 여러가지 질문이 떠오를 것이다. private network에선 외부로 나가지 않고 바로 접속할 수 없나? private network가 아닌 경우 public network에선 어떻게 해야하나? tcp가 아니라 udp환경이면? web이라면 websocket을 사용할 수 있는가? 무엇보다 처음 노드를 시작해서 어떻게 찾아가야하는가? 등등 물음표가 가득하다. |
| title | libp2p 연재 - 2. Node 생성 |
| author | acidsound |
| permlink | libp2p-2-node |
| json metadata | {"tags":["kr-dev","kr","libp2p"],"image":["https://cdn.steemitimages.com/DQmeZmBPzT1aETMhGSqNUGPEhaJUzzwka93u7oYP68hnzAt/image.png"],"links":["https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggTFJcbmxpYnAycC0tPmJ1bmRsZVxubGlicDJwLXRjcC0tPmJ1bmRsZVxucGVlci1pbmZvLS0-Y3JlYXRlTm9kZVxuYnVuZGxlLS0-Y3JlYXRlTm9kZVxuY3JlYXRlTm9kZS0tPmluZGV4IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0","https://github.com/libp2p/js-libp2p#libp2phandleprotocol-handlerfunc--matchfunc","https://github.com/libp2p/js-libp2p#libp2pdialprotocolpeer-protocol-callback"],"app":"steemit/0.1","format":"markdown"} |
| parent author | |
| parent permlink | kr-dev |
| Transaction Info | Block #36963201/Trx 86ea51752bb72c759a1888ff589c8a5d8e78f1e2 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "맥북 키보드 수리하느라 꽤 오랜 날을 보냈다.\n여튼 두번째 글!\n이제 p2p다운 걸 좀 해보자. peer to peer로 접근하고 메시지를 주고 받는 것이 이번 목표다.\n\n## 복습\n\n전에 만든 index.js를 다시 보자.\n\n```javascript\nconst Bundle = require('./bundle');\nconst PeerInfo = require('peer-info');\nconsole.log(\"peer is creating...\");\nPeerInfo.create((err, peerInfo)=> {\n console.log(\"peerID is\", peerInfo.id._idB58String);\n peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0');\n const node = new Bundle({ peerInfo });\n node.start(err=> {\n if (err) { throw err; }\n console.log(node.peerInfo.multiaddrs.toArray().map(o=>o.toString()));\n });\n});\n```\n\n## Refactoring\n\n실제로 PeerInfo.create를 통해 node를 생성하고 시작하는 것까지 했는데 이걸 node의 생성이란 것으로 일반화할 수 있다.\n그러면 createNode라는 function을 만들고 node 자체를 가져오게 하면 어떨까?\n\n```javascript\nconst Bundle = require('./bundle');\nconst PeerInfo = require('peer-info');\nconsole.log(\"peer is creating...\");\n\nconst createNode = () => new Promise((resolve, reject) => {\n PeerInfo.create((err, peerInfo) => {\n peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0');\n const node = new Bundle({peerInfo});\n node.start(err => {\n if (err) {\n reject(err);\n }\n resolve(node);\n });\n });\n});\n\ncreateNode()\n .then(node =>\n console.log(\n node.peerInfo.multiaddrs.toArray().map(o => o.toString())\n )\n );\n```\n\n어짜피 알고 싶은 건 node니까 Promise로 받아오고 createNode.js 라는 파일로 분리해보자.\n\n```javascript\nconst Bundle = require('./bundle');\nconst PeerInfo = require('peer-info');\n\nconst createNode = ()=> new Promise((resolve, reject) => {\n PeerInfo.create((err, peerInfo) => {\n peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0');\n const node = new Bundle({peerInfo});\n node.start(err => err && reject(err) || resolve(node))\n });\n});\n\nmodule.exports = createNode;\n```\n\n이제 createNode를 require하도록 index.js를 수정하자.\n\n```javascript\nconst createNode = require('./createNode');\ncreateNode()\n .then(node =>\n console.log(\n node.peerInfo.multiaddrs.toArray().map(o => o.toString())\n )\n );\n```\n\n꽤 간단한 구조다. [그래프참조](https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggTFJcbmxpYnAycC0tPmJ1bmRsZVxubGlicDJwLXRjcC0tPmJ1bmRsZVxucGVlci1pbmZvLS0-Y3JlYXRlTm9kZVxuYnVuZGxlLS0-Y3JlYXRlTm9kZVxuY3JlYXRlTm9kZS0tPmluZGV4IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0)\n\n```mermaid\ngraph LR\nlibp2p-->bundle\nlibp2p-tcp-->bundle\npeer-info-->createNode\nbundle-->createNode\ncreateNode-->index\n```\n\n## Dial to Handle\n\n그럼 이제 node간 통신을 구현해볼 차례다\n\npeer간 통신을 protocol이라는 경로를 통해 구현해보자.\n\n그러기 위해 handle(https://github.com/libp2p/js-libp2p#libp2phandleprotocol-handlerfunc--matchfunc) 을 통해 새로운 프로토콜에 대한 응답을 만들고 dialProtocol(https://github.com/libp2p/js-libp2p#libp2pdialprotocolpeer-protocol-callback)로 접근을 시도해본다.\n\ncreateNode에서 얻은 node 객체로 handle과 dialProtocol을 구현해보니\n\n```javascript\ncreateNode()\n .then(node => {\n node.handle('/print', (protocol, conn) => console.log('dialed successfully'));\n node.dialProtocol(node.peerInfo, '/print', (err, conn) => { if (err) throw err });\n });\n```\n\n결과는\n\n```\nError: A node cannot dial itself\n```\n\n란다. 스스로 node는 자신에게 dial을 할 수 없다.\n\n그렇다면 두개의 node를 생성해서 한쪽은 handle, 한쪽은 dialProtocol을 호출하도록 구현하자.\n\n두개의 node가 필요하므로 Promise.all로 배열을 만든 뒤 nodes 라는 배열로 받자.\n\n전체 index.js의 구현은 다음과 같다.\n\n```javascript\nconst createNode = require('./createNode');\n\n// createNode()\n// .then(node => {\n// node.handle('/print', (protocol, conn) => console.log('dialed successfully'));\n// node.dialProtocol(node.peerInfo, '/print', (err, conn) => { if (err) throw err });\n// });\n\nPromise.all([createNode(), createNode()])\n .then(nodes => {\n nodes.forEach((node, idx) => console.log(idx, node.peerInfo.multiaddrs.toArray().map(o => o.toString())));\n nodes[0].handle('/print', (protocol, conn) => {\n console.log(\"node1 dialed to node0 successfully\");\n });\n nodes[1].dialProtocol(nodes[0].peerInfo, '/print', (err, conn) => {\n if (err) throw err;\n console.log('dialProtocol conn:', conn.peerInfo.id._idB58String);\n });\n });\n```\n\n별거 없다. \n\n1. nodes[1]이 dialProtocol을 /print 라는 protocol로 하고\n2. nodes[0]가 handle에서 응답한 후 \n3. nodes[1]의 dialProtocol의 callBack을 호출한다.\n\n실행해보자.\n\n```\n0 [ '/ip4/127.0.0.1/tcp/60894/ipfs/QmTrs4KkyUXvjEhPKYnUhu1vUoy9e9yPpVytqnLsovNY6Y',\n'/ip4/192.168.0.59/tcp/60894/ipfs/QmTrs4KkyUXvjEhPKYnUhu1vUoy9e9yPpVytqnLsovNY6Y' ]\n1 [ '/ip4/127.0.0.1/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz', '/ip4/192.168.0.59/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz' ]\nnode1 dialed to node0 successfully\ndialProtocol conn: QmTrs4KkyUXvjEhPKYnUhu1vUoy9e9yPpVytqnLsovNY6Y\n```\n\n예상한대로 나왔다.\n\n여기서 흥미로운 점은 dialProtocol의 callback에서 인자로 넘어온 conn은 dialProtocol을 실행한 자신이 아니라 호출한 대상인 node라는 점이다.\n\n## 다른 인스턴스에서 dial하기\n\nnode REPL(node)을 열고 handle과 dial을 따로 실행해보자.\n\n터미널 두개를 열고 한쪽에는 아래와 같이 handle을 한줄 한줄 입력하고\n\n```javascript\ncreateNode = require('./createNode')\nlet node;\ncreateNode.then(o => node);\nconsole.log(node.peerInfo.multiaddrs.toArray().map(o=>o.toString()));\nnode.handle('/print', ()=>console.log('dialed'));\n```\n\n여기까지하면 multiaddr 주소가 보일 것이다.\n\n```json\n[ '/ip4/127.0.0.1/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz', '/ip4/192.168.0.59/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz' ]\n```\n\n다른 한쪽엔 dial을 걸어보자.\n\n두번째 ('/ip4/192.168.0.59/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz') 주소를 일단 복사를 해두자.\n\n 터미널을 하나 더 열고 dialProtocol을 해보자.\n\n```javascript\ncreateNode = require('./createNode');\nlet node;\ncreateNode.then(o => node);\nnode.dialProtocol('/ip4/192.168.0.59/tcp/60895/ipfs/QmUwe9fauAd4jJrQEPGdLXptz5yChhHSL9gLbyVvcjexjz', '/print', ()=>console.log(err, \"\"))\n```\n\n문제가 없다면 첫번째 handle 을 하고 있던 터미널 창에 ```dialed```라고 반응할 것이다.\n\n지금쯤 여러가지 질문이 떠오를 것이다. private network에선 외부로 나가지 않고 바로 접속할 수 없나? private network가 아닌 경우 public network에선 어떻게 해야하나? tcp가 아니라 udp환경이면? web이라면 websocket을 사용할 수 있는가? 무엇보다 처음 노드를 시작해서 어떻게 찾아가야하는가? 등등 물음표가 가득하다.",
"title": "libp2p 연재 - 2. Node 생성",
"author": "acidsound",
"permlink": "libp2p-2-node",
"json_metadata": "{\"tags\":[\"kr-dev\",\"kr\",\"libp2p\"],\"image\":[\"https://cdn.steemitimages.com/DQmeZmBPzT1aETMhGSqNUGPEhaJUzzwka93u7oYP68hnzAt/image.png\"],\"links\":[\"https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggTFJcbmxpYnAycC0tPmJ1bmRsZVxubGlicDJwLXRjcC0tPmJ1bmRsZVxucGVlci1pbmZvLS0-Y3JlYXRlTm9kZVxuYnVuZGxlLS0-Y3JlYXRlTm9kZVxuY3JlYXRlTm9kZS0tPmluZGV4IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0\",\"https://github.com/libp2p/js-libp2p#libp2phandleprotocol-handlerfunc--matchfunc\",\"https://github.com/libp2p/js-libp2p#libp2pdialprotocolpeer-protocol-callback\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
"parent_author": "",
"parent_permlink": "kr-dev"
}
],
"block": 36963201,
"trx_id": "86ea51752bb72c759a1888ff589c8a5d8e78f1e2",
"op_in_trx": 0,
"timestamp": "2019-10-03T14:58:00",
"virtual_op": false,
"trx_in_block": 15
}drugwarssent 0.001 HIVE to @acidsound- "DrugWars Reminder : The Purge is happening today at Midnight UTC. Few hours left before the goverment raid. Read more about the purge here : https://steemit.com/drugwars/@drugwars/drugwars-current-sta..."2019/09/30 17:25:15
drugwarssent 0.001 HIVE to @acidsound- "DrugWars Reminder : The Purge is happening today at Midnight UTC. Few hours left before the goverment raid. Read more about the purge here : https://steemit.com/drugwars/@drugwars/drugwars-current-sta..."
2019/09/30 17:25:15
| to | acidsound |
| from | drugwars |
| memo | DrugWars Reminder : The Purge is happening today at Midnight UTC. Few hours left before the goverment raid. Read more about the purge here : https://steemit.com/drugwars/@drugwars/drugwars-current-state-economics-purge-v6-and-v7-etc |
| amount | 0.001 HIVE |
| Transaction Info | Block #36879921/Trx 29e58bfbeb4f13208512c13b93b026d7bf9b788f |
View Raw JSON Data
{
"op": [
"transfer",
{
"to": "acidsound",
"from": "drugwars",
"memo": "DrugWars Reminder : The Purge is happening today at Midnight UTC. Few hours left before the goverment raid. Read more about the purge here : https://steemit.com/drugwars/@drugwars/drugwars-current-state-economics-purge-v6-and-v7-etc",
"amount": "0.001 HIVE"
}
],
"block": 36879921,
"trx_id": "29e58bfbeb4f13208512c13b93b026d7bf9b788f",
"op_in_trx": 42,
"timestamp": "2019-09-30T17:25:15",
"virtual_op": false,
"trx_in_block": 35
}steemitboardeffective vote applied for @acidsound / msgib9g7t542019/09/28 09:53:51
steemitboardeffective vote applied for @acidsound / msgib9g7t54
2019/09/28 09:53:51
| voter | steemitboard |
| author | acidsound |
| weight | 8012 (80.12%) |
| rshares | 16073708037 |
| permlink | msgib9g7t54 |
| pending payout | 0.003 HBD |
| total vote weight | 8012 |
| Transaction Info | Block #36813439/Trx a0533d46726f8cacef2ebb2f97ab174cfdb27c84 |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "steemitboard",
"author": "acidsound",
"weight": 8012,
"rshares": 16073708037,
"permlink": "msgib9g7t54",
"pending_payout": "0.003 HBD",
"total_vote_weight": 8012
}
],
"block": 36813439,
"trx_id": "a0533d46726f8cacef2ebb2f97ab174cfdb27c84",
"op_in_trx": 1,
"timestamp": "2019-09-28T09:53:51",
"virtual_op": true,
"trx_in_block": 5
}steemitboardupvoted (1.00%) @acidsound / msgib9g7t542019/09/28 09:53:51
steemitboardupvoted (1.00%) @acidsound / msgib9g7t54
2019/09/28 09:53:51
| voter | steemitboard |
| author | acidsound |
| weight | 100 (1.00%) |
| permlink | msgib9g7t54 |
| Transaction Info | Block #36813439/Trx a0533d46726f8cacef2ebb2f97ab174cfdb27c84 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "steemitboard",
"author": "acidsound",
"weight": 100,
"permlink": "msgib9g7t54"
}
],
"block": 36813439,
"trx_id": "a0533d46726f8cacef2ebb2f97ab174cfdb27c84",
"op_in_trx": 0,
"timestamp": "2019-09-28T09:53:51",
"virtual_op": false,
"trx_in_block": 5
}2019/09/28 09:53:48
2019/09/28 09:53:48
| body | Congratulations @acidsound! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) : <table><tr><td><img src="https://steemitimages.com/60x70/http://steemitboard.com/@acidsound/posts.png?201909280919"></td><td>You published more than 20 posts. Your next target is to reach 30 posts.</td></tr> </table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@acidsound) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=acidsound)_</sub> <sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub> To support your work, I also upvoted your post! ###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes! |
| title | |
| author | steemitboard |
| permlink | steemitboard-notify-acidsound-20190928t095344000z |
| json metadata | {"image":["https://steemitboard.com/img/notify.png"]} |
| parent author | acidsound |
| parent permlink | msgib9g7t54 |
| Transaction Info | Block #36813438/Trx 16f14f717a8379694a145381c7cbd80d6e42e0ae |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "Congratulations @acidsound! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :\n\n<table><tr><td><img src=\"https://steemitimages.com/60x70/http://steemitboard.com/@acidsound/posts.png?201909280919\"></td><td>You published more than 20 posts. Your next target is to reach 30 posts.</td></tr>\n</table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@acidsound) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=acidsound)_</sub>\n<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>\n\n\nTo support your work, I also upvoted your post!\n\n\n###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!",
"title": "",
"author": "steemitboard",
"permlink": "steemitboard-notify-acidsound-20190928t095344000z",
"json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
"parent_author": "acidsound",
"parent_permlink": "msgib9g7t54"
}
],
"block": 36813438,
"trx_id": "16f14f717a8379694a145381c7cbd80d6e42e0ae",
"op_in_trx": 0,
"timestamp": "2019-09-28T09:53:48",
"virtual_op": false,
"trx_in_block": 7
}acidsoundupdated options for msgib9g7t542019/09/28 09:26:15
acidsoundupdated options for msgib9g7t54
2019/09/28 09:26:15
| author | acidsound |
| permlink | msgib9g7t54 |
| extensions | [[0,{"beneficiaries":[{"weight":1000,"account":"dtube"}]}]] |
| allow votes | true |
| percent hbd | 10000 |
| max accepted payout | 1000000.000 HBD |
| allow curation rewards | true |
| Transaction Info | Block #36812889/Trx 2b47a2f81ede854c25b3a63308e9810a9682e01e |
View Raw JSON Data
{
"op": [
"comment_options",
{
"author": "acidsound",
"permlink": "msgib9g7t54",
"extensions": [
[
0,
{
"beneficiaries": [
{
"weight": 1000,
"account": "dtube"
}
]
}
]
],
"allow_votes": true,
"percent_hbd": 10000,
"max_accepted_payout": "1000000.000 HBD",
"allow_curation_rewards": true
}
],
"block": 36812889,
"trx_id": "2b47a2f81ede854c25b3a63308e9810a9682e01e",
"op_in_trx": 1,
"timestamp": "2019-09-28T09:26:15",
"virtual_op": false,
"trx_in_block": 10
}acidsoundpublished a new post: msgib9g7t542019/09/28 09:26:15
acidsoundpublished a new post: msgib9g7t54
2019/09/28 09:26:15
| body | <center><a href='https://d.tube/#!/v/acidsound/msgib9g7t54'><img src='https://snap1.d.tube/ipfs/QmaKtYh3nSeoZErWkorQb52F1UFLMNjF6VuGVUNURiYHFB'></a></center><hr> gtr tapping is so fun! <hr><a href='https://d.tube/#!/v/acidsound/msgib9g7t54'> ▶️ DTube</a><br /><a href='https://ipfs.io/ipfs/QmNV9E6VewpQDKGkULGSSpDDmWNouQpYSo1UXnu5y3SFZB'> ▶️ IPFS</a> |
| title | NAPPA(by crush) iPad garageband cover |
| author | acidsound |
| permlink | msgib9g7t54 |
| json metadata | {"video":{"videoId":"QmNV9E6VewpQDKGkULGSSpDDmWNouQpYSo1UXnu5y3SFZB","duration":123.31333333333333,"title":"NAPPA(by crush) iPad garageband cover","description":"gtr tapping is so fun!","filesize":31468091,"ipfs":{"snaphash":"QmQTXHSEdSobzoJUUzuioLj6uRBZ5Gu33GUqGqZtbkDjPV","spritehash":"QmdZMDzJpQju8hTfsJfgJR7usApuM8HjHSeC2r1eM6TMqf","videohash":"QmNV9E6VewpQDKGkULGSSpDDmWNouQpYSo1UXnu5y3SFZB","video240hash":"QmeQfHKrYsFzW9j8wLvS2vVvPmzEKrZkw9SFy5FMHthXWy","video480hash":"QmWu9NndkdJVeJRz7Pe7ULe7q1Db9TYAUiDm2jVtoBpQ2g"},"thumbnailUrl":"https://snap1.d.tube/ipfs/QmQTXHSEdSobzoJUUzuioLj6uRBZ5Gu33GUqGqZtbkDjPV","providerName":"IPFS","refs":["dtc/spectrum00/QmNV9E6VewpQDKGkULGSSpDDmWNouQpYSo1UXnu5y3SFZB"]},"tags":["dtube","music"],"app":"dtube/0.9"} |
| parent author | |
| parent permlink | dtube |
| Transaction Info | Block #36812889/Trx 2b47a2f81ede854c25b3a63308e9810a9682e01e |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "<center><a href='https://d.tube/#!/v/acidsound/msgib9g7t54'><img src='https://snap1.d.tube/ipfs/QmaKtYh3nSeoZErWkorQb52F1UFLMNjF6VuGVUNURiYHFB'></a></center><hr>\n\ngtr tapping is so fun!\n\n<hr><a href='https://d.tube/#!/v/acidsound/msgib9g7t54'> ▶️ DTube</a><br /><a href='https://ipfs.io/ipfs/QmNV9E6VewpQDKGkULGSSpDDmWNouQpYSo1UXnu5y3SFZB'> ▶️ IPFS</a>",
"title": "NAPPA(by crush) iPad garageband cover",
"author": "acidsound",
"permlink": "msgib9g7t54",
"json_metadata": "{\"video\":{\"videoId\":\"QmNV9E6VewpQDKGkULGSSpDDmWNouQpYSo1UXnu5y3SFZB\",\"duration\":123.31333333333333,\"title\":\"NAPPA(by crush) iPad garageband cover\",\"description\":\"gtr tapping is so fun!\",\"filesize\":31468091,\"ipfs\":{\"snaphash\":\"QmQTXHSEdSobzoJUUzuioLj6uRBZ5Gu33GUqGqZtbkDjPV\",\"spritehash\":\"QmdZMDzJpQju8hTfsJfgJR7usApuM8HjHSeC2r1eM6TMqf\",\"videohash\":\"QmNV9E6VewpQDKGkULGSSpDDmWNouQpYSo1UXnu5y3SFZB\",\"video240hash\":\"QmeQfHKrYsFzW9j8wLvS2vVvPmzEKrZkw9SFy5FMHthXWy\",\"video480hash\":\"QmWu9NndkdJVeJRz7Pe7ULe7q1Db9TYAUiDm2jVtoBpQ2g\"},\"thumbnailUrl\":\"https://snap1.d.tube/ipfs/QmQTXHSEdSobzoJUUzuioLj6uRBZ5Gu33GUqGqZtbkDjPV\",\"providerName\":\"IPFS\",\"refs\":[\"dtc/spectrum00/QmNV9E6VewpQDKGkULGSSpDDmWNouQpYSo1UXnu5y3SFZB\"]},\"tags\":[\"dtube\",\"music\"],\"app\":\"dtube/0.9\"}",
"parent_author": "",
"parent_permlink": "dtube"
}
],
"block": 36812889,
"trx_id": "2b47a2f81ede854c25b3a63308e9810a9682e01e",
"op_in_trx": 0,
"timestamp": "2019-09-28T09:26:15",
"virtual_op": false,
"trx_in_block": 10
}acidsoundupdated options for v101a59uobd2019/09/28 08:29:39
acidsoundupdated options for v101a59uobd
2019/09/28 08:29:39
| author | acidsound |
| permlink | v101a59uobd |
| extensions | [[0,{"beneficiaries":[{"weight":1000,"account":"dtube"}]}]] |
| allow votes | true |
| percent hbd | 10000 |
| max accepted payout | 1000000.000 HBD |
| allow curation rewards | true |
| Transaction Info | Block #36811758/Trx 79ace3c61c0f89a327798024a6bfabc4741e61a0 |
View Raw JSON Data
{
"op": [
"comment_options",
{
"author": "acidsound",
"permlink": "v101a59uobd",
"extensions": [
[
0,
{
"beneficiaries": [
{
"weight": 1000,
"account": "dtube"
}
]
}
]
],
"allow_votes": true,
"percent_hbd": 10000,
"max_accepted_payout": "1000000.000 HBD",
"allow_curation_rewards": true
}
],
"block": 36811758,
"trx_id": "79ace3c61c0f89a327798024a6bfabc4741e61a0",
"op_in_trx": 1,
"timestamp": "2019-09-28T08:29:39",
"virtual_op": false,
"trx_in_block": 29
}acidsoundpublished a new post: v101a59uobd2019/09/28 08:29:39
acidsoundpublished a new post: v101a59uobd
2019/09/28 08:29:39
| body | <center><a href='https://d.tube/#!/v/acidsound/v101a59uobd'><img src='https://i.ytimg.com/vi/xYRxYrKFZRE/maxresdefault.jpg'></a></center><hr> https://www.youtube.com/watch?v=xYRxYrKFZRE 나빠빠빠 빠빠. 기타연습하니 개러지밴드 연주가 는다. <hr><a href='https://d.tube/#!/v/acidsound/v101a59uobd'> ▶️ DTube</a><br /><a href='https://www.youtube.com/watch?v=xYRxYrKFZRE'> ▶️ YouTube</a> |
| title | 나빠(NAPPA by crush) Cover /w garageband |
| author | acidsound |
| permlink | v101a59uobd |
| json metadata | {"video":{"videoId":"xYRxYrKFZRE","url":"https://www.youtube.com/watch?v=xYRxYrKFZRE","title":"나빠(NAPPA by crush) Cover /w garageband","description":"나빠빠빠 빠빠. 기타연습하니 개러지밴드 연주가 는다.","owner":"jaeho lee","channelId":"UCvjzR9wnJeBNzeLDYboHfmw","thumbnailUrl":"https://i.ytimg.com/vi/xYRxYrKFZRE/maxresdefault.jpg","datePublished":"2019-09-11","genre":"Science & Technology","isFamilyFriendly":true,"duration":124,"channelThumbnailUrl":"https://yt3.ggpht.com/a/AGF-l7_w5vbAh7Jy0Vq6QVs6-Bq9oF66ufkQVFctcw=s48-c-k-c0xffffffff-no-rj-mo","providerName":"YouTube","app":"dtube/0.9","refs":[]},"tags":["dtube","music"],"app":"dtube/0.9"} |
| parent author | |
| parent permlink | dtube |
| Transaction Info | Block #36811758/Trx 79ace3c61c0f89a327798024a6bfabc4741e61a0 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "<center><a href='https://d.tube/#!/v/acidsound/v101a59uobd'><img src='https://i.ytimg.com/vi/xYRxYrKFZRE/maxresdefault.jpg'></a></center><hr>\n\nhttps://www.youtube.com/watch?v=xYRxYrKFZRE\n\n나빠빠빠 빠빠. 기타연습하니 개러지밴드 연주가 는다.\n\n<hr><a href='https://d.tube/#!/v/acidsound/v101a59uobd'> ▶️ DTube</a><br /><a href='https://www.youtube.com/watch?v=xYRxYrKFZRE'> ▶️ YouTube</a>",
"title": "나빠(NAPPA by crush) Cover /w garageband",
"author": "acidsound",
"permlink": "v101a59uobd",
"json_metadata": "{\"video\":{\"videoId\":\"xYRxYrKFZRE\",\"url\":\"https://www.youtube.com/watch?v=xYRxYrKFZRE\",\"title\":\"나빠(NAPPA by crush) Cover /w garageband\",\"description\":\"나빠빠빠 빠빠. 기타연습하니 개러지밴드 연주가 는다.\",\"owner\":\"jaeho lee\",\"channelId\":\"UCvjzR9wnJeBNzeLDYboHfmw\",\"thumbnailUrl\":\"https://i.ytimg.com/vi/xYRxYrKFZRE/maxresdefault.jpg\",\"datePublished\":\"2019-09-11\",\"genre\":\"Science & Technology\",\"isFamilyFriendly\":true,\"duration\":124,\"channelThumbnailUrl\":\"https://yt3.ggpht.com/a/AGF-l7_w5vbAh7Jy0Vq6QVs6-Bq9oF66ufkQVFctcw=s48-c-k-c0xffffffff-no-rj-mo\",\"providerName\":\"YouTube\",\"app\":\"dtube/0.9\",\"refs\":[]},\"tags\":[\"dtube\",\"music\"],\"app\":\"dtube/0.9\"}",
"parent_author": "",
"parent_permlink": "dtube"
}
],
"block": 36811758,
"trx_id": "79ace3c61c0f89a327798024a6bfabc4741e61a0",
"op_in_trx": 0,
"timestamp": "2019-09-28T08:29:39",
"virtual_op": false,
"trx_in_block": 29
}drugwarssent 0.001 HIVE to @acidsound- "DrugWars - The Purge will happen the 30 September 2019 (at Midnight UTC). Only inactive players will be impacted. Read more about the purge here : https://steemit.com/drugwars/@drugwars/drugwars-curre..."2019/09/23 23:28:12
drugwarssent 0.001 HIVE to @acidsound- "DrugWars - The Purge will happen the 30 September 2019 (at Midnight UTC). Only inactive players will be impacted. Read more about the purge here : https://steemit.com/drugwars/@drugwars/drugwars-curre..."
2019/09/23 23:28:12
| to | acidsound |
| from | drugwars |
| memo | DrugWars - The Purge will happen the 30 September 2019 (at Midnight UTC). Only inactive players will be impacted. Read more about the purge here : https://steemit.com/drugwars/@drugwars/drugwars-current-state-economics-purge-v6-and-v7-etc |
| amount | 0.001 HIVE |
| Transaction Info | Block #36685997/Trx 967200ceddc034b771f43ee0d1dcaac93c8a12e2 |
View Raw JSON Data
{
"op": [
"transfer",
{
"to": "acidsound",
"from": "drugwars",
"memo": "DrugWars - The Purge will happen the 30 September 2019 (at Midnight UTC). Only inactive players will be impacted. Read more about the purge here : https://steemit.com/drugwars/@drugwars/drugwars-current-state-economics-purge-v6-and-v7-etc",
"amount": "0.001 HIVE"
}
],
"block": 36685997,
"trx_id": "967200ceddc034b771f43ee0d1dcaac93c8a12e2",
"op_in_trx": 3,
"timestamp": "2019-09-23T23:28:12",
"virtual_op": false,
"trx_in_block": 0
}dtubesent 0.001 HIVE to @acidsound- "Time is running out, claim your DTube account now before anyone else can! Login at https://d.tube"2019/08/22 16:12:09
dtubesent 0.001 HIVE to @acidsound- "Time is running out, claim your DTube account now before anyone else can! Login at https://d.tube"
2019/08/22 16:12:09
| to | acidsound |
| from | dtube |
| memo | Time is running out, claim your DTube account now before anyone else can! Login at https://d.tube |
| amount | 0.001 HIVE |
| Transaction Info | Block #35779451/Trx 1fe617878941df4fde0fbea189062fd68e15a0a3 |
View Raw JSON Data
{
"op": [
"transfer",
{
"to": "acidsound",
"from": "dtube",
"memo": "Time is running out, claim your DTube account now before anyone else can! Login at https://d.tube",
"amount": "0.001 HIVE"
}
],
"block": 35779451,
"trx_id": "1fe617878941df4fde0fbea189062fd68e15a0a3",
"op_in_trx": 18,
"timestamp": "2019-08-22T16:12:09",
"virtual_op": false,
"trx_in_block": 7
}2019/06/23 20:23:48
2019/06/23 20:23:48
| body | Congratulations @acidsound! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@acidsound/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@acidsound) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=acidsound)_</sub> **Do not miss the last post from @steemitboard:** <table><tr><td><a href="https://steemit.com/steemitboard/@steemitboard/the-steem-community-has-lost-an-epic-member-farewell-woflhart"><img src="https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmQWnM36SWCPGn98nY83M1ArgweMz5fnovQEp2E4FiDdug/Wolfhart_header.png"></a></td><td><a href="https://steemit.com/steemitboard/@steemitboard/the-steem-community-has-lost-an-epic-member-farewell-woflhart">The Steem community has lost an epic member! Farewell @woflhart!</a></td></tr><tr><td><a href="https://steemit.com/steemtoolbar/@steemitboard/steemtoolbar-update-display-bug-fixed"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/7CiQEO.png"></a></td><td><a href="https://steemit.com/steemtoolbar/@steemitboard/steemtoolbar-update-display-bug-fixed">SteemitBoard - Witness Update</a></td></tr><tr><td><a href="https://steemit.com/steem/@steemitboard/do-not-miss-the-coming-rocky-mountain-steem-meetup-and-get-a-new-community-badge"><img src="https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmUphCGZFWgt6bJ1XTtunV7esnwy6bxnGqcLcHAV3NEqnQ/meetup-rocky-mountain.png"></a></td><td><a href="https://steemit.com/steem/@steemitboard/do-not-miss-the-coming-rocky-mountain-steem-meetup-and-get-a-new-community-badge">Do not miss the coming Rocky Mountain Steem Meetup and get a new community badge!</a></td></tr></table> ###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes! |
| title | |
| author | steemitboard |
| permlink | steemitboard-notify-acidsound-20190623t202344000z |
| json metadata | {"image":["https://steemitboard.com/img/notify.png"]} |
| parent author | acidsound |
| parent permlink | libp2p-1-node |
| Transaction Info | Block #34060256/Trx 63ee552b46e8ea91239f2c34c80be8466a825939 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "Congratulations @acidsound! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@acidsound/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@acidsound) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=acidsound)_</sub>\n\n\n**Do not miss the last post from @steemitboard:**\n<table><tr><td><a href=\"https://steemit.com/steemitboard/@steemitboard/the-steem-community-has-lost-an-epic-member-farewell-woflhart\"><img src=\"https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmQWnM36SWCPGn98nY83M1ArgweMz5fnovQEp2E4FiDdug/Wolfhart_header.png\"></a></td><td><a href=\"https://steemit.com/steemitboard/@steemitboard/the-steem-community-has-lost-an-epic-member-farewell-woflhart\">The Steem community has lost an epic member! Farewell @woflhart!</a></td></tr><tr><td><a href=\"https://steemit.com/steemtoolbar/@steemitboard/steemtoolbar-update-display-bug-fixed\"><img src=\"https://steemitimages.com/64x128/http://i.cubeupload.com/7CiQEO.png\"></a></td><td><a href=\"https://steemit.com/steemtoolbar/@steemitboard/steemtoolbar-update-display-bug-fixed\">SteemitBoard - Witness Update</a></td></tr><tr><td><a href=\"https://steemit.com/steem/@steemitboard/do-not-miss-the-coming-rocky-mountain-steem-meetup-and-get-a-new-community-badge\"><img src=\"https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmUphCGZFWgt6bJ1XTtunV7esnwy6bxnGqcLcHAV3NEqnQ/meetup-rocky-mountain.png\"></a></td><td><a href=\"https://steemit.com/steem/@steemitboard/do-not-miss-the-coming-rocky-mountain-steem-meetup-and-get-a-new-community-badge\">Do not miss the coming Rocky Mountain Steem Meetup and get a new community badge!</a></td></tr></table>\n\n###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!",
"title": "",
"author": "steemitboard",
"permlink": "steemitboard-notify-acidsound-20190623t202344000z",
"json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
"parent_author": "acidsound",
"parent_permlink": "libp2p-1-node"
}
],
"block": 34060256,
"trx_id": "63ee552b46e8ea91239f2c34c80be8466a825939",
"op_in_trx": 0,
"timestamp": "2019-06-23T20:23:48",
"virtual_op": false,
"trx_in_block": 3
}acidsoundcustom json: drugwars2019/05/16 04:30:21
acidsoundcustom json: drugwars
2019/05/16 04:30:21
| id | drugwars |
| json | {"date":"2019-05-16T04:30:09.145Z"} |
| required auths | [] |
| required posting auths | ["acidsound"] |
| Transaction Info | Block #32948148/Trx acce9b54eee04d8601d719af1be38754315c0b51 |
View Raw JSON Data
{
"op": [
"custom_json",
{
"id": "drugwars",
"json": "{\"date\":\"2019-05-16T04:30:09.145Z\"}",
"required_auths": [],
"required_posting_auths": [
"acidsound"
]
}
],
"block": 32948148,
"trx_id": "acce9b54eee04d8601d719af1be38754315c0b51",
"op_in_trx": 0,
"timestamp": "2019-05-16T04:30:21",
"virtual_op": false,
"trx_in_block": 69
}acidsoundcustom json: drugwars2019/03/31 17:55:06
acidsoundcustom json: drugwars
2019/03/31 17:55:06
| id | drugwars |
| json | "U2FsdGVkX18swLXhMstRFHEkazI6c69UcCBOkJHsWD2M5DobzrwYlWfH7XVqnCSPK30JREwyBJe3iEKKLRxnGJcjSw0Por21LdPobLPor21LdCk6M8VCcy0eFxMl3JkQlzATxxMl3Jksug8dIxMl3JkaqWorlbYOxMl3Jk3jztnPor21LdQqCCZ5Yw2AMl32Ml32" |
| required auths | [] |
| required posting auths | ["acidsound"] |
| Transaction Info | Block #31641792/Trx 360892ff14d06507e8a25c6fc80d9e6798c4191f |
View Raw JSON Data
{
"op": [
"custom_json",
{
"id": "drugwars",
"json": "\"U2FsdGVkX18swLXhMstRFHEkazI6c69UcCBOkJHsWD2M5DobzrwYlWfH7XVqnCSPK30JREwyBJe3iEKKLRxnGJcjSw0Por21LdPobLPor21LdCk6M8VCcy0eFxMl3JkQlzATxxMl3Jksug8dIxMl3JkaqWorlbYOxMl3Jk3jztnPor21LdQqCCZ5Yw2AMl32Ml32\"",
"required_auths": [],
"required_posting_auths": [
"acidsound"
]
}
],
"block": 31641792,
"trx_id": "360892ff14d06507e8a25c6fc80d9e6798c4191f",
"op_in_trx": 0,
"timestamp": "2019-03-31T17:55:06",
"virtual_op": false,
"trx_in_block": 62
}acidsoundcustom json: drugwars2019/03/31 17:54:51
acidsoundcustom json: drugwars
2019/03/31 17:54:51
| id | drugwars |
| json | "U2FsdGVkX1xMl3Jkaf8ItRi6zmPor21LdiHBSe9TVCZQCEzdggLZFF0Quk6OtmqhwxOMFhFBP6BbN9fOWt8JN6UPzfAzyt3MSlASD2serYy7nkZ0pqLscIj89joGEqLysZwOmrkYxMl3JkT2R9PX96Xi2duRSV4y30961AMl32Ml32" |
| required auths | [] |
| required posting auths | ["acidsound"] |
| Transaction Info | Block #31641787/Trx 73dc28d16980235f952d11fc0a69b31e529ffb8d |
View Raw JSON Data
{
"op": [
"custom_json",
{
"id": "drugwars",
"json": "\"U2FsdGVkX1xMl3Jkaf8ItRi6zmPor21LdiHBSe9TVCZQCEzdggLZFF0Quk6OtmqhwxOMFhFBP6BbN9fOWt8JN6UPzfAzyt3MSlASD2serYy7nkZ0pqLscIj89joGEqLysZwOmrkYxMl3JkT2R9PX96Xi2duRSV4y30961AMl32Ml32\"",
"required_auths": [],
"required_posting_auths": [
"acidsound"
]
}
],
"block": 31641787,
"trx_id": "73dc28d16980235f952d11fc0a69b31e529ffb8d",
"op_in_trx": 0,
"timestamp": "2019-03-31T17:54:51",
"virtual_op": false,
"trx_in_block": 53
}acidsoundcustom json: drugwars2019/03/31 17:54:45
acidsoundcustom json: drugwars
2019/03/31 17:54:45
| id | drugwars |
| json | "U2FsdGVkX1Por21LdJQQiOOjNd1OGsya7WbjmBR42GMvDAm3WtDLq5VpUoLejSz9MLdfa1I5xMl3JkjriVTsPkUtOeURoGvfVuOqfn0ZPor21LdvIAxMl3JkpGs4vV7dI6USF3rpBawYeph8J05FBws0xMl3JkvEmCMTz3HwdjO0EUtsgMl32Ml32" |
| required auths | [] |
| required posting auths | ["acidsound"] |
| Transaction Info | Block #31641785/Trx 0b82e267d7223c273c473fcb20fedf89484d5c1f |
View Raw JSON Data
{
"op": [
"custom_json",
{
"id": "drugwars",
"json": "\"U2FsdGVkX1Por21LdJQQiOOjNd1OGsya7WbjmBR42GMvDAm3WtDLq5VpUoLejSz9MLdfa1I5xMl3JkjriVTsPkUtOeURoGvfVuOqfn0ZPor21LdvIAxMl3JkpGs4vV7dI6USF3rpBawYeph8J05FBws0xMl3JkvEmCMTz3HwdjO0EUtsgMl32Ml32\"",
"required_auths": [],
"required_posting_auths": [
"acidsound"
]
}
],
"block": 31641785,
"trx_id": "0b82e267d7223c273c473fcb20fedf89484d5c1f",
"op_in_trx": 0,
"timestamp": "2019-03-31T17:54:45",
"virtual_op": false,
"trx_in_block": 11
}acidsoundcustom json: dw-char2019/03/31 17:54:15
acidsoundcustom json: dw-char
2019/03/31 17:54:15
| id | dw-char |
| json | {"user_id":"5","username":"acidsound","icon":"5","referrer":null} |
| required auths | [] |
| required posting auths | ["acidsound"] |
| Transaction Info | Block #31641775/Trx 52d2e120f36a00621ac1625193a19ca93f8915cc |
View Raw JSON Data
{
"op": [
"custom_json",
{
"id": "dw-char",
"json": "{\"user_id\":\"5\",\"username\":\"acidsound\",\"icon\":\"5\",\"referrer\":null}",
"required_auths": [],
"required_posting_auths": [
"acidsound"
]
}
],
"block": 31641775,
"trx_id": "52d2e120f36a00621ac1625193a19ca93f8915cc",
"op_in_trx": 0,
"timestamp": "2019-03-31T17:54:15",
"virtual_op": false,
"trx_in_block": 16
}acidsoundupdated their account properties2019/03/31 17:54:03
acidsoundupdated their account properties
2019/03/31 17:54:03
| account | acidsound |
| posting | {"key_auths":[["STM5vtTJdVuVcZetoHAsLatsv8y8foagwqLdPpbCCATzWXeJni9YG",1]],"account_auths":[["busy.app",1],["ctube.app",1],["dlive.app",1],["drugwars.app",1],["dtube.app",1]],"weight_threshold":1} |
| memo key | STM82LaqLJ2DqX13NiYEFAucd1XVyHchG879nMYfXajBEgYkfJAfQ |
| json metadata | {"profile":{"profile_image":"https://gravatar.com/avatar/c1f9e3fc81c451788df421e46fda5c21?size=400","name":"acidsound","about":"function과 reactive를 좋아하는 플루티스트"}} |
| Transaction Info | Block #31641771/Trx 633b647210fda558df0e714df66ff17ae85ffc7c |
View Raw JSON Data
{
"op": [
"account_update",
{
"account": "acidsound",
"posting": {
"key_auths": [
[
"STM5vtTJdVuVcZetoHAsLatsv8y8foagwqLdPpbCCATzWXeJni9YG",
1
]
],
"account_auths": [
[
"busy.app",
1
],
[
"ctube.app",
1
],
[
"dlive.app",
1
],
[
"drugwars.app",
1
],
[
"dtube.app",
1
]
],
"weight_threshold": 1
},
"memo_key": "STM82LaqLJ2DqX13NiYEFAucd1XVyHchG879nMYfXajBEgYkfJAfQ",
"json_metadata": "{\"profile\":{\"profile_image\":\"https://gravatar.com/avatar/c1f9e3fc81c451788df421e46fda5c21?size=400\",\"name\":\"acidsound\",\"about\":\"function과 reactive를 좋아하는 플루티스트\"}}"
}
],
"block": 31641771,
"trx_id": "633b647210fda558df0e714df66ff17ae85ffc7c",
"op_in_trx": 0,
"timestamp": "2019-03-31T17:54:03",
"virtual_op": false,
"trx_in_block": 20
}dleasesent 0.001 HIVE to @acidsound- "BuildTeam is proud to announce the release of DLease.io - our flagship P2P leasing marketplace app, aimed at assisting Steemians in leasing and delegating STEEM POWER for daily passive returns, with r..."2019/03/12 11:41:09
dleasesent 0.001 HIVE to @acidsound- "BuildTeam is proud to announce the release of DLease.io - our flagship P2P leasing marketplace app, aimed at assisting Steemians in leasing and delegating STEEM POWER for daily passive returns, with r..."
2019/03/12 11:41:09
| to | acidsound |
| from | dlease |
| memo | BuildTeam is proud to announce the release of DLease.io - our flagship P2P leasing marketplace app, aimed at assisting Steemians in leasing and delegating STEEM POWER for daily passive returns, with recent yields as high as 20% APR. DLease.io is a professional grade app , designed to replace the current MinnowBooster.net leasing market which has to date facilitated nearly 20 Million STEEM POWER in lease value to happy BuildTeam customers. View the new app at https://dlease.io/ or read the announcement post on https://steemit.com/@dlease. |
| amount | 0.001 HIVE |
| Transaction Info | Block #31087462/Trx af92d89ad1adc8e1974583e6481f832cdc7b1d24 |
View Raw JSON Data
{
"op": [
"transfer",
{
"to": "acidsound",
"from": "dlease",
"memo": "BuildTeam is proud to announce the release of DLease.io - our flagship P2P leasing marketplace app, aimed at assisting Steemians in leasing and delegating STEEM POWER for daily passive returns, with recent yields as high as 20% APR. DLease.io is a professional grade app , designed to replace the current MinnowBooster.net leasing market which has to date facilitated nearly 20 Million STEEM POWER in lease value to happy BuildTeam customers. View the new app at https://dlease.io/ or read the announcement post on https://steemit.com/@dlease.",
"amount": "0.001 HIVE"
}
],
"block": 31087462,
"trx_id": "af92d89ad1adc8e1974583e6481f832cdc7b1d24",
"op_in_trx": 0,
"timestamp": "2019-03-12T11:41:09",
"virtual_op": false,
"trx_in_block": 14
}2019/02/23 12:44:24
2019/02/23 12:44:24
| author | acidsound |
| permlink | re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z |
| Transaction Info | Block #30599472/Virtual Operation 4294967295:2 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z"
}
],
"block": 30599472,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 2,
"timestamp": "2019-02-23T12:44:24",
"virtual_op": true,
"trx_in_block": 4294967295
}stepanowonupvoted (100.00%) @acidsound / graphql-advanced-graphql-mutation-query2019/02/17 01:55:00
stepanowonupvoted (100.00%) @acidsound / graphql-advanced-graphql-mutation-query
2019/02/17 01:55:00
| voter | stepanowon |
| author | acidsound |
| weight | 10000 (100.00%) |
| permlink | graphql-advanced-graphql-mutation-query |
| Transaction Info | Block #30413813/Trx 284d0625563955d91b0b5a1e83dd65f0c697d54c |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "stepanowon",
"author": "acidsound",
"weight": 10000,
"permlink": "graphql-advanced-graphql-mutation-query"
}
],
"block": 30413813,
"trx_id": "284d0625563955d91b0b5a1e83dd65f0c697d54c",
"op_in_trx": 0,
"timestamp": "2019-02-17T01:55:00",
"virtual_op": false,
"trx_in_block": 12
}2019/02/17 01:54:48
2019/02/17 01:54:48
| body | 의외의 좋은 기법이네요.. 꿀팁입니다.. |
| title | |
| author | stepanowon |
| permlink | re-acidsound-graphql-advanced-graphql-mutation-query-20190217t015445954z |
| json metadata | {"tags":["kr"],"app":"steemit/0.1"} |
| parent author | acidsound |
| parent permlink | graphql-advanced-graphql-mutation-query |
| Transaction Info | Block #30413809/Trx ec544764e72c824b7834b1c62fc628b8a9c826ef |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "의외의 좋은 기법이네요.. 꿀팁입니다..",
"title": "",
"author": "stepanowon",
"permlink": "re-acidsound-graphql-advanced-graphql-mutation-query-20190217t015445954z",
"json_metadata": "{\"tags\":[\"kr\"],\"app\":\"steemit/0.1\"}",
"parent_author": "acidsound",
"parent_permlink": "graphql-advanced-graphql-mutation-query"
}
],
"block": 30413809,
"trx_id": "ec544764e72c824b7834b1c62fc628b8a9c826ef",
"op_in_trx": 0,
"timestamp": "2019-02-17T01:54:48",
"virtual_op": false,
"trx_in_block": 30
}2019/02/16 14:05:00
2019/02/16 14:05:00
| body | Congratulations @acidsound! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) : <table><tr><td>https://steemitimages.com/60x60/http://steemitboard.com/notifications/firstcommented.png</td><td>You got a First Reply</td></tr> <tr><td>https://steemitimages.com/60x70/http://steemitboard.com/@acidsound/comments.png?201902161322</td><td>You made more than 10 comments. Your next target is to reach 50 comments.</td></tr> </table> <sub>_[Click here to view your Board](https://steemitboard.com/@acidsound)_</sub> <sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub> **Do not miss the last post from @steemitboard:** <table><tr><td><a href="https://steemit.com/valentine/@steemitboard/valentine-challenge-love-is-in-the-air"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/LvDzr5.png"></a></td><td><a href="https://steemit.com/valentine/@steemitboard/valentine-challenge-love-is-in-the-air">Valentine challenge - Love is in the air!</a></td></tr></table> > Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**! |
| title | |
| author | steemitboard |
| permlink | steemitboard-notify-acidsound-20190216t140459000z |
| json metadata | {"image":["https://steemitboard.com/img/notify.png"]} |
| parent author | acidsound |
| parent permlink | libp2p-1-node |
| Transaction Info | Block #30399622/Trx 3c1500f69f0f44e5a562647e5a7a6f4c0cc4c71c |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "Congratulations @acidsound! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :\n\n<table><tr><td>https://steemitimages.com/60x60/http://steemitboard.com/notifications/firstcommented.png</td><td>You got a First Reply</td></tr>\n<tr><td>https://steemitimages.com/60x70/http://steemitboard.com/@acidsound/comments.png?201902161322</td><td>You made more than 10 comments. Your next target is to reach 50 comments.</td></tr>\n</table>\n\n<sub>_[Click here to view your Board](https://steemitboard.com/@acidsound)_</sub>\n<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>\n\n\n\n**Do not miss the last post from @steemitboard:**\n<table><tr><td><a href=\"https://steemit.com/valentine/@steemitboard/valentine-challenge-love-is-in-the-air\"><img src=\"https://steemitimages.com/64x128/http://i.cubeupload.com/LvDzr5.png\"></a></td><td><a href=\"https://steemit.com/valentine/@steemitboard/valentine-challenge-love-is-in-the-air\">Valentine challenge - Love is in the air!</a></td></tr></table>\n\n> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!",
"title": "",
"author": "steemitboard",
"permlink": "steemitboard-notify-acidsound-20190216t140459000z",
"json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
"parent_author": "acidsound",
"parent_permlink": "libp2p-1-node"
}
],
"block": 30399622,
"trx_id": "3c1500f69f0f44e5a562647e5a7a6f4c0cc4c71c",
"op_in_trx": 0,
"timestamp": "2019-02-16T14:05:00",
"virtual_op": false,
"trx_in_block": 31
}2019/02/16 12:47:15
2019/02/16 12:47:15
| body | Apologies in advance for the spam. This is an automated comment to reduce the voting power of @fulltimegeek, a flat earth retard who is flagging reputable users like @themadcurator, @themarkymark and myself because he's a whiny little bitch who is throwing a hissy fit.<br><br>Please support these users and follow @themadcurator and @themarkymark.<br><br>Thank you for your attention. |
| title | |
| author | berniesanders |
| permlink | berniesanders-re-acidsoundre-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z |
| json metadata | |
| parent author | acidsound |
| parent permlink | re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z |
| Transaction Info | Block #30398067/Trx 9185333ac279eabeb8ff8ce2ce66943c039a3ed1 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "Apologies in advance for the spam. This is an automated comment to reduce the voting power of @fulltimegeek, a flat earth retard who is flagging reputable users like @themadcurator, @themarkymark and myself because he's a whiny little bitch who is throwing a hissy fit.<br><br>Please support these users and follow @themadcurator and @themarkymark.<br><br>Thank you for your attention.",
"title": "",
"author": "berniesanders",
"permlink": "berniesanders-re-acidsoundre-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z",
"json_metadata": "",
"parent_author": "acidsound",
"parent_permlink": "re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z"
}
],
"block": 30398067,
"trx_id": "9185333ac279eabeb8ff8ce2ce66943c039a3ed1",
"op_in_trx": 0,
"timestamp": "2019-02-16T12:47:15",
"virtual_op": false,
"trx_in_block": 16
}berniesanderseffective vote applied for @acidsound / re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z2019/02/16 12:47:12
berniesanderseffective vote applied for @acidsound / re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z
2019/02/16 12:47:12
| voter | berniesanders |
| author | acidsound |
| weight | 1399 (13.99%) |
| rshares | 57980409 |
| permlink | re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z |
| pending payout | 0.000 HBD |
| total vote weight | 7634 |
| Transaction Info | Block #30398066/Trx 57f247c61c6a4e438f920ee91fc2cd251e06c04f |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "berniesanders",
"author": "acidsound",
"weight": 1399,
"rshares": 57980409,
"permlink": "re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z",
"pending_payout": "0.000 HBD",
"total_vote_weight": 7634
}
],
"block": 30398066,
"trx_id": "57f247c61c6a4e438f920ee91fc2cd251e06c04f",
"op_in_trx": 1,
"timestamp": "2019-02-16T12:47:12",
"virtual_op": true,
"trx_in_block": 21
}2019/02/16 12:47:12
2019/02/16 12:47:12
| voter | berniesanders |
| author | acidsound |
| weight | 1 (0.01%) |
| permlink | re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z |
| Transaction Info | Block #30398066/Trx 57f247c61c6a4e438f920ee91fc2cd251e06c04f |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "berniesanders",
"author": "acidsound",
"weight": 1,
"permlink": "re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z"
}
],
"block": 30398066,
"trx_id": "57f247c61c6a4e438f920ee91fc2cd251e06c04f",
"op_in_trx": 0,
"timestamp": "2019-02-16T12:47:12",
"virtual_op": false,
"trx_in_block": 21
}2019/02/16 12:44:27
2019/02/16 12:44:27
| body | 아놔 진짜 launchpad 망했네. 나님 선견지명 무엇?  |
| title | |
| author | acidsound |
| permlink | re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z |
| json metadata | {"tags":["kr"],"image":["https://cdn.steemitimages.com/DQmR7RbD2hqtKzUVGizVBAJsDbvU9PCrbaZyYd8kMi6qhb2/image.png"],"app":"steemit/0.1"} |
| parent author | acidsound |
| parent permlink | re-acidsound-graphql-advanced-graphql-mutation-query-20180506t194012494z |
| Transaction Info | Block #30398011/Trx 78f27ddfff0870eb122a46864c148f2d0c45ef3c |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "아놔 진짜 launchpad 망했네. 나님 선견지명 무엇?\n",
"title": "",
"author": "acidsound",
"permlink": "re-acidsound-re-acidsound-graphql-advanced-graphql-mutation-query-20190216t124423924z",
"json_metadata": "{\"tags\":[\"kr\"],\"image\":[\"https://cdn.steemitimages.com/DQmR7RbD2hqtKzUVGizVBAJsDbvU9PCrbaZyYd8kMi6qhb2/image.png\"],\"app\":\"steemit/0.1\"}",
"parent_author": "acidsound",
"parent_permlink": "re-acidsound-graphql-advanced-graphql-mutation-query-20180506t194012494z"
}
],
"block": 30398011,
"trx_id": "78f27ddfff0870eb122a46864c148f2d0c45ef3c",
"op_in_trx": 0,
"timestamp": "2019-02-16T12:44:27",
"virtual_op": false,
"trx_in_block": 13
}2019/01/18 03:26:42
2019/01/18 03:26:42
| body | [](https://partiko-io.app.link/A27hLeUkgT) |
| title | |
| author | partiko |
| permlink | partiko-re-acidsound-libp2p-1-node-20190118t032639498z |
| json metadata | {"app":"partiko"} |
| parent author | acidsound |
| parent permlink | libp2p-1-node |
| Transaction Info | Block #29552441/Trx 3d8588e9303691247f692500294836442a474458 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "[](https://partiko-io.app.link/A27hLeUkgT)",
"title": "",
"author": "partiko",
"permlink": "partiko-re-acidsound-libp2p-1-node-20190118t032639498z",
"json_metadata": "{\"app\":\"partiko\"}",
"parent_author": "acidsound",
"parent_permlink": "libp2p-1-node"
}
],
"block": 29552441,
"trx_id": "3d8588e9303691247f692500294836442a474458",
"op_in_trx": 0,
"timestamp": "2019-01-18T03:26:42",
"virtual_op": false,
"trx_in_block": 7
}acidsoundupdated payout for libp2p-1-node2018/12/08 13:32:39
acidsoundupdated payout for libp2p-1-node
2018/12/08 13:32:39
| author | acidsound |
| permlink | libp2p-1-node |
| Transaction Info | Block #28384638/Virtual Operation 4294967295:24 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "libp2p-1-node"
}
],
"block": 28384638,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 24,
"timestamp": "2018-12-08T13:32:39",
"virtual_op": true,
"trx_in_block": 4294967295
}mishanaeffective vote applied for @acidsound / libp2p-1-node2018/12/01 14:03:54
mishanaeffective vote applied for @acidsound / libp2p-1-node
2018/12/01 14:03:54
| voter | mishana |
| author | acidsound |
| weight | 55266 |
| rshares | 14487747185 |
| permlink | libp2p-1-node |
| pending payout | 0.015 HBD |
| total vote weight | 160617 |
| Transaction Info | Block #28183766/Trx 0cf8de87d41c0e06a199b10d436c0bed35d9fbaf |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "mishana",
"author": "acidsound",
"weight": 55266,
"rshares": 14487747185,
"permlink": "libp2p-1-node",
"pending_payout": "0.015 HBD",
"total_vote_weight": 160617
}
],
"block": 28183766,
"trx_id": "0cf8de87d41c0e06a199b10d436c0bed35d9fbaf",
"op_in_trx": 1,
"timestamp": "2018-12-01T14:03:54",
"virtual_op": true,
"trx_in_block": 34
}mishanaupvoted (60.00%) @acidsound / libp2p-1-node2018/12/01 14:03:54
mishanaupvoted (60.00%) @acidsound / libp2p-1-node
2018/12/01 14:03:54
| voter | mishana |
| author | acidsound |
| weight | 6000 (60.00%) |
| permlink | libp2p-1-node |
| Transaction Info | Block #28183766/Trx 0cf8de87d41c0e06a199b10d436c0bed35d9fbaf |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "mishana",
"author": "acidsound",
"weight": 6000,
"permlink": "libp2p-1-node"
}
],
"block": 28183766,
"trx_id": "0cf8de87d41c0e06a199b10d436c0bed35d9fbaf",
"op_in_trx": 0,
"timestamp": "2018-12-01T14:03:54",
"virtual_op": false,
"trx_in_block": 34
}codingarteffective vote applied for @acidsound / libp2p-1-node2018/12/01 13:52:27
codingarteffective vote applied for @acidsound / libp2p-1-node
2018/12/01 13:52:27
| voter | codingart |
| author | acidsound |
| weight | 105351 |
| rshares | 10437385536 |
| permlink | libp2p-1-node |
| pending payout | 0.006 HBD |
| total vote weight | 105351 |
| Transaction Info | Block #28183537/Trx 736c750b7f3332332f95aec120ffff91dcf6c264 |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "codingart",
"author": "acidsound",
"weight": 105351,
"rshares": 10437385536,
"permlink": "libp2p-1-node",
"pending_payout": "0.006 HBD",
"total_vote_weight": 105351
}
],
"block": 28183537,
"trx_id": "736c750b7f3332332f95aec120ffff91dcf6c264",
"op_in_trx": 1,
"timestamp": "2018-12-01T13:52:27",
"virtual_op": true,
"trx_in_block": 41
}codingartupvoted (50.00%) @acidsound / libp2p-1-node2018/12/01 13:52:27
codingartupvoted (50.00%) @acidsound / libp2p-1-node
2018/12/01 13:52:27
| voter | codingart |
| author | acidsound |
| weight | 5000 (50.00%) |
| permlink | libp2p-1-node |
| Transaction Info | Block #28183537/Trx 736c750b7f3332332f95aec120ffff91dcf6c264 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "codingart",
"author": "acidsound",
"weight": 5000,
"permlink": "libp2p-1-node"
}
],
"block": 28183537,
"trx_id": "736c750b7f3332332f95aec120ffff91dcf6c264",
"op_in_trx": 0,
"timestamp": "2018-12-01T13:52:27",
"virtual_op": false,
"trx_in_block": 41
}allazsent 0.001 HBD to @acidsound- "Promote your post. Your post will be min. 10 resteemed with over 13000 followers and min. 25 Upvote Different account (5000 STEEM POWER). Your post will be more popular and you will find new frien..."2018/12/01 13:35:12
allazsent 0.001 HBD to @acidsound- "Promote your post. Your post will be min. 10 resteemed with over 13000 followers and min. 25 Upvote Different account (5000 STEEM POWER). Your post will be more popular and you will find new frien..."
2018/12/01 13:35:12
| to | acidsound |
| from | allaz |
| memo | Promote your post. Your post will be min. 10 resteemed with over 13000 followers and min. 25 Upvote Different account (5000 STEEM POWER). Your post will be more popular and you will find new friends. Send 0.5 SBD or STEEM to @allaz (post URL as memo ) Service Active. |
| amount | 0.001 HBD |
| Transaction Info | Block #28183192/Trx ed8a37ff360b133651e6d993501148f1541e3ef9 |
View Raw JSON Data
{
"op": [
"transfer",
{
"to": "acidsound",
"from": "allaz",
"memo": "Promote your post. Your post will be min. 10 resteemed with over 13000 followers and min. 25 Upvote Different account (5000 STEEM POWER). Your post will be more popular and you will find new friends. Send 0.5 SBD or STEEM to @allaz (post URL as memo ) Service Active.",
"amount": "0.001 HBD"
}
],
"block": 28183192,
"trx_id": "ed8a37ff360b133651e6d993501148f1541e3ef9",
"op_in_trx": 0,
"timestamp": "2018-12-01T13:35:12",
"virtual_op": false,
"trx_in_block": 3
}acidsoundpublished a new post: libp2p-1-node2018/12/01 13:32:42
acidsoundpublished a new post: libp2p-1-node
2018/12/01 13:32:42
| body | p2p, 즉 server없는 - 요즘 유행하는 serverless 어쩌고 하는 이상한 거 말고 - peer간 통신쪽을 쭉 보고 있다. IPFS(InterPlanetary File System)을 보면서 꽤 흥미롭다고 생각했는데 사실 매번 파일을 저장할 필요는 없다고 생각해서 IPFS를 구성하는 libp2p를 좀 살펴보기로 했다. IPFS도 그렇지만 한글 문서는 둘째치고 영문으로도 실제로 뭔가 해본 글이 별로 없어서 본진(https://github.com/libp2p/js-libp2p/tree/master/examples)의 Examples 와 Tutorials 를 보면서 하나씩 해보고 있다. libp2p내용은 네트웍에서 암호화까지 굉장히 많은 범위를 다루고 있으므로 어디서부터 학습을 시작할지 진입로를 찾는 것이 쉽지 않았다. 이 글에선 최대한 노이즈를 적게하면서 작은 부분 부터 하나씩 쫓아가보는 것을 목표로 한다. ## peer 만들기 가장 먼저할 것은 유일하며 독립적인 peer를 만드는 일이다. node.js 에서 가볍게 시작해보자. ``` mkdir p2pconn cd p2pconn npm init -y npm install --save libp2p libp2p-tcp peer-info ``` npm install 에서 c파일들을 컴파일 하느라 약간 시간이 걸린다. package.json을 cat package.json으로 확인해보면 대략 아래와 같을 것이다. ``` $ cat package.json { "name": "p2pconn", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "libp2p": "^0.23.1", "libp2p-tcp": "^0.13.0", "peer-info": "^0.14.1" } } ``` test 부분을 start로 바꿔주고 index.js를 실행하게끔 변경하자. ``` { "name": "p2pconn", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node index.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "libp2p": "^0.23.1", "libp2p-tcp": "^0.13.0", "peer-info": "^0.14.1" } } ``` index.js를 생성하자. 제일 먼저 통신을 할 주체인 peer를 생성하는 것부터 시작해보자. ```javascript const PeerInfo = require('peer-info'); PeerInfo.create((err, peerInfo)=>{ console.log(peerInfo); }); ```` 간단하다. PeerInfo 객체의 method인 create를 통해 peer의 정보를 생성하는데 npm start로 실행해보면 결과는 다음과 같다. ``` PeerInfo { id: PeerId { _id: <Buffer 12 20 ae df d4 ac 88 d1 ca cc f2 45 39 af b9 45 29 c7 be 74 1a cf da 05 37 ae 67 4e 3b ab 7f ba 61 74>, _idB58String: 'Qma7Hc6rWEU9kj8cnvpjR75QDDLKy5XcnTmvUSiVJWdDF9', _privKey: RsaPrivateKey { _key: [Object], _publicKey: [Object] }, _pubKey: undefined }, multiaddrs: MultiaddrSet { _multiaddrs: [], _observedMultiaddrs: [] }, protocols: Set {}, _connectedMultiaddr: undefined } Process finished with exit code 0 ``` 아마 IPFS를 써본 적이 있는 분이라면 _idB58String: 'Qma7Hc6rWEU9kj8cnvpjR75QDDLKy5XcnTmvUSiVJWdDF9' 이 부분이 눈에 들어올 것이라고 생각한다. 이 값은 매번 실행할때마다 새로 생성되는 해쉬값이며 중복이 되지 않는다. peerInfo에서 필요한 건 일단 이 식별자이다. 잘 기억해놓자. ## Bundle 만들기 사실 libp2p를 하기 위해 제일 먼저 할 일은 libp2p를 상속받은 Bundle class를 만드는 일이다. 이 Bundle class의 constructor에 인자로 어떤 module들을 사용할지 지정할 수 있다. 일단 TCP 모듈을 사용해서 TCP 네트워트 안에서 자신을 식별할 수 있도록 해보자. libp2p-tcp모듈을 사용한다. bundle.js를 만들어보자. ``` const libp2p = require('libp2p'); const TCP = require('libp2p-tcp'); class Bundle extends libp2p { constructor(_options) { const defaults = { modules: { transport: [ TCP ] } }; super({...defaults, ..._options}); } } module.exports = Bundle; ``` 이런 형태가 될 것이다. 인자가 생긴 모양을 잘 보자. modules.transport 가 array 형을 인자로 갖고 거기에 모듈인 libp2p-tcp를 끼워넣었다. bundle을 만들었으면 이제 실제로 node instance를 생성해보자. Node 생성 node는 node = new Bundle()로 인스턴스를 생성하면 되는데 public network에서 닿을 수 있도록 0.0.0.0을 peer정보에 지정해서 생성해본다. ``` peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0'); ``` 를 index.js에 추가하고 bundle.js를 가져와서 peerInfo를 넣어주자. ``` const Bundle = require('./bundle'); const PeerInfo = require('peer-info'); console.log("peer is creating..."); PeerInfo.create((err, peerInfo)=> { console.log("peerID is", peerInfo.id._idB58String); peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0'); const node = new Bundle({ peerInfo }); node.start(err=> { if (err) { throw err; } console.log(node.peerInfo.multiaddrs.toArray().map(o=>o.toString())); }); }); ``` index.js 를 이와 같이 수정했다. Bundle class에 multiaddrs를 추가한 peerInfo를 가지고 node를 생성하고 node의 start function을 실행하여 정상적으로 시작한 경우 node가 가지고 있는 peerInfo의 주소들을 전부 출력하도록 했다. 아마 제대로 했다면 다음과 같은 결과를 볼 수 있을 것이다. ``` peer is creating... peerID is QmXvU5Gmjy2GGotqP1CHggEffbtQ3ptbZJtxT48g2AkvLD [ '/ip4/127.0.0.1/tcp/49170/ipfs/QmXvU5Gmjy2GGotqP1CHggEffbtQ3ptbZJtxT48g2AkvLD', '/ip4/192.168.0.79/tcp/49170/ipfs/QmXvU5Gmjy2GGotqP1CHggEffbtQ3ptbZJtxT48g2AkvLD' ] ``` peerId가 같은 127.0.0.1 주소와 private IP(혹은 public IP)를 볼 수 있을 것이다. 결과는 네트웍 상황에 따라 다를 수 있다. 여러번 실행해보면 tcp 뒤에 붙는 port 와 ipfs 뒤에 붙는 peerId가 계속 바뀌는 걸 볼 수 있다. 여기까지 보다보니 multiaddrs라는게 나왔다. peerInfo(https://github.com/libp2p/js-peer-info)도 mutliaddrs(https://github.com/multiformats/multiaddr)도 도대체 모르는 것들 투성이다. 지금 상황에서 모든 걸 다 알아보고 쫓아가기엔 조금 힘들다. 호기심을 가지고 계속 다음으로 전진하자. |
| title | libp2p 연재 - 1. Node 생성 |
| author | acidsound |
| permlink | libp2p-1-node |
| json metadata | {"tags":["kr-dev","kr","libp2p"],"links":["https://github.com/libp2p/js-libp2p/tree/master/examples","https://github.com/libp2p/js-peer-info","https://github.com/multiformats/multiaddr"],"app":"steemit/0.1","format":"markdown"} |
| parent author | |
| parent permlink | kr-dev |
| Transaction Info | Block #28183142/Trx 9efa0d41d10768e01eb073a4b86cea47d1ee5347 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "p2p, 즉 server없는 - 요즘 유행하는 serverless 어쩌고 하는 이상한 거 말고 - peer간 통신쪽을 쭉 보고 있다.\n\nIPFS(InterPlanetary File System)을 보면서 꽤 흥미롭다고 생각했는데 사실 매번 파일을 저장할 필요는 없다고 생각해서 IPFS를 구성하는 libp2p를 좀 살펴보기로 했다.\n\nIPFS도 그렇지만 한글 문서는 둘째치고 영문으로도 실제로 뭔가 해본 글이 별로 없어서 본진(https://github.com/libp2p/js-libp2p/tree/master/examples)의 Examples 와 Tutorials 를 보면서 하나씩 해보고 있다.\n\nlibp2p내용은 네트웍에서 암호화까지 굉장히 많은 범위를 다루고 있으므로 어디서부터 학습을 시작할지 진입로를 찾는 것이 쉽지 않았다.\n\n이 글에선 최대한 노이즈를 적게하면서 작은 부분 부터 하나씩 쫓아가보는 것을 목표로 한다.\n\n## peer 만들기\n가장 먼저할 것은 유일하며 독립적인 peer를 만드는 일이다.\n\nnode.js 에서 가볍게 시작해보자.\n```\nmkdir p2pconn\ncd p2pconn\nnpm init -y\nnpm install --save libp2p libp2p-tcp peer-info\n```\nnpm install 에서 c파일들을 컴파일 하느라 약간 시간이 걸린다.\n\npackage.json을 cat package.json으로 확인해보면 대략 아래와 같을 것이다.\n```\n$ cat package.json \n{\n \"name\": \"p2pconn\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"libp2p\": \"^0.23.1\",\n \"libp2p-tcp\": \"^0.13.0\",\n \"peer-info\": \"^0.14.1\"\n }\n}\n```\ntest 부분을 start로 바꿔주고 index.js를 실행하게끔 변경하자.\n```\n{\n \"name\": \"p2pconn\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"start\": \"node index.js\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"libp2p\": \"^0.23.1\",\n \"libp2p-tcp\": \"^0.13.0\",\n \"peer-info\": \"^0.14.1\"\n }\n}\n```\nindex.js를 생성하자.\n\n제일 먼저 통신을 할 주체인 peer를 생성하는 것부터 시작해보자.\n```javascript\nconst PeerInfo = require('peer-info');\n\nPeerInfo.create((err, peerInfo)=>{\n console.log(peerInfo);\n});\n````\n간단하다. PeerInfo 객체의 method인 create를 통해 peer의 정보를 생성하는데 npm start로 실행해보면 결과는 다음과 같다.\n```\nPeerInfo {\n id:\n PeerId {\n _id:\n <Buffer 12 20 ae df d4 ac 88 d1 ca cc f2 45 39 af b9 45 29 c7 be 74 1a cf da 05 37 ae 67 4e 3b ab 7f ba 61 74>,\n _idB58String: 'Qma7Hc6rWEU9kj8cnvpjR75QDDLKy5XcnTmvUSiVJWdDF9',\n _privKey: RsaPrivateKey { _key: [Object], _publicKey: [Object] },\n _pubKey: undefined },\n multiaddrs: MultiaddrSet { _multiaddrs: [], _observedMultiaddrs: [] },\n protocols: Set {},\n _connectedMultiaddr: undefined }\n\nProcess finished with exit code 0\n```\n아마 IPFS를 써본 적이 있는 분이라면 _idB58String: 'Qma7Hc6rWEU9kj8cnvpjR75QDDLKy5XcnTmvUSiVJWdDF9' 이 부분이 눈에 들어올 것이라고 생각한다.\n\n이 값은 매번 실행할때마다 새로 생성되는 해쉬값이며 중복이 되지 않는다.\n\npeerInfo에서 필요한 건 일단 이 식별자이다. 잘 기억해놓자.\n\n## Bundle 만들기\n사실 libp2p를 하기 위해 제일 먼저 할 일은 libp2p를 상속받은 Bundle class를 만드는 일이다.\n\n이 Bundle class의 constructor에 인자로 어떤 module들을 사용할지 지정할 수 있다.\n\n일단 TCP 모듈을 사용해서 TCP 네트워트 안에서 자신을 식별할 수 있도록 해보자.\n\nlibp2p-tcp모듈을 사용한다. bundle.js를 만들어보자.\n```\nconst libp2p = require('libp2p');\nconst TCP = require('libp2p-tcp');\nclass Bundle extends libp2p {\n constructor(_options) {\n const defaults = {\n modules: {\n transport: [\n TCP\n ]\n } \n };\n super({...defaults, ..._options});\n }\n}\nmodule.exports = Bundle;\n```\n이런 형태가 될 것이다. 인자가 생긴 모양을 잘 보자.\n\nmodules.transport 가 array 형을 인자로 갖고 거기에 모듈인 libp2p-tcp를 끼워넣었다.\n\nbundle을 만들었으면 이제 실제로 node instance를 생성해보자.\n\nNode 생성\nnode는 node = new Bundle()로 인스턴스를 생성하면 되는데 public network에서 닿을 수 있도록 0.0.0.0을 peer정보에 지정해서 생성해본다.\n```\npeerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0');\n```\n를 index.js에 추가하고 bundle.js를 가져와서 peerInfo를 넣어주자.\n```\nconst Bundle = require('./bundle');\nconst PeerInfo = require('peer-info');\nconsole.log(\"peer is creating...\");\nPeerInfo.create((err, peerInfo)=> {\n console.log(\"peerID is\", peerInfo.id._idB58String);\n peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0');\n const node = new Bundle({ peerInfo });\n node.start(err=> {\n if (err) { throw err; }\n console.log(node.peerInfo.multiaddrs.toArray().map(o=>o.toString()));\n });\n});\n```\nindex.js 를 이와 같이 수정했다.\n\nBundle class에 multiaddrs를 추가한 peerInfo를 가지고 node를 생성하고 node의 start function을 실행하여 정상적으로 시작한 경우 node가 가지고 있는 peerInfo의 주소들을 전부 출력하도록 했다.\n\n아마 제대로 했다면 다음과 같은 결과를 볼 수 있을 것이다.\n```\npeer is creating...\npeerID is QmXvU5Gmjy2GGotqP1CHggEffbtQ3ptbZJtxT48g2AkvLD\n[ '/ip4/127.0.0.1/tcp/49170/ipfs/QmXvU5Gmjy2GGotqP1CHggEffbtQ3ptbZJtxT48g2AkvLD',\n '/ip4/192.168.0.79/tcp/49170/ipfs/QmXvU5Gmjy2GGotqP1CHggEffbtQ3ptbZJtxT48g2AkvLD' ]\n```\npeerId가 같은 127.0.0.1 주소와 private IP(혹은 public IP)를 볼 수 있을 것이다. 결과는 네트웍 상황에 따라 다를 수 있다.\n\n여러번 실행해보면 tcp 뒤에 붙는 port 와 ipfs 뒤에 붙는 peerId가 계속 바뀌는 걸 볼 수 있다.\n\n여기까지 보다보니 multiaddrs라는게 나왔다.\n\npeerInfo(https://github.com/libp2p/js-peer-info)도 mutliaddrs(https://github.com/multiformats/multiaddr)도 도대체 모르는 것들 투성이다.\n\n지금 상황에서 모든 걸 다 알아보고 쫓아가기엔 조금 힘들다. 호기심을 가지고 계속 다음으로 전진하자.",
"title": "libp2p 연재 - 1. Node 생성",
"author": "acidsound",
"permlink": "libp2p-1-node",
"json_metadata": "{\"tags\":[\"kr-dev\",\"kr\",\"libp2p\"],\"links\":[\"https://github.com/libp2p/js-libp2p/tree/master/examples\",\"https://github.com/libp2p/js-peer-info\",\"https://github.com/multiformats/multiaddr\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
"parent_author": "",
"parent_permlink": "kr-dev"
}
],
"block": 28183142,
"trx_id": "9efa0d41d10768e01eb073a4b86cea47d1ee5347",
"op_in_trx": 0,
"timestamp": "2018-12-01T13:32:42",
"virtual_op": false,
"trx_in_block": 20
}2018/09/19 08:36:39
2018/09/19 08:36:39
| author | acidsound |
| permlink | d65fm8r3 |
| Transaction Info | Block #26076435/Virtual Operation 4294967295:2 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "d65fm8r3"
}
],
"block": 26076435,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 2,
"timestamp": "2018-09-19T08:36:39",
"virtual_op": true,
"trx_in_block": 4294967295
}2018/09/19 07:19:51
2018/09/19 07:19:51
| author | acidsound |
| permlink | ui3g8uo4 |
| Transaction Info | Block #26074899/Virtual Operation 4294967295:2 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "ui3g8uo4"
}
],
"block": 26074899,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 2,
"timestamp": "2018-09-19T07:19:51",
"virtual_op": true,
"trx_in_block": 4294967295
}2018/09/19 05:11:45
2018/09/19 05:11:45
| author | acidsound |
| permlink | jt511hy6 |
| Transaction Info | Block #26072340/Virtual Operation 4294967295:2 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "jt511hy6"
}
],
"block": 26072340,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 2,
"timestamp": "2018-09-19T05:11:45",
"virtual_op": true,
"trx_in_block": 4294967295
}2018/09/17 04:34:45
2018/09/17 04:34:45
| author | acidsound |
| permlink | kbzrcb8x |
| Transaction Info | Block #26029589/Virtual Operation 4294967295:3 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "kbzrcb8x"
}
],
"block": 26029589,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 3,
"timestamp": "2018-09-17T04:34:45",
"virtual_op": true,
"trx_in_block": 4294967295
}acidsounddeleted a comment or post2018/09/14 04:10:06
acidsounddeleted a comment or post
2018/09/14 04:10:06
| author | acidsound |
| permlink | 8vpzv0im |
| Transaction Info | Block #25942727/Trx 5d4e4b1e078a7e4d34a28eb3c07af20bfe6c293b |
View Raw JSON Data
{
"op": [
"delete_comment",
{
"author": "acidsound",
"permlink": "8vpzv0im"
}
],
"block": 25942727,
"trx_id": "5d4e4b1e078a7e4d34a28eb3c07af20bfe6c293b",
"op_in_trx": 0,
"timestamp": "2018-09-14T04:10:06",
"virtual_op": false,
"trx_in_block": 24
}2018/09/14 02:10:42
2018/09/14 02:10:42
| author | acidsound |
| permlink | 8vpzv0im |
| extensions | [[0,{"beneficiaries":[{"weight":2500,"account":"acidsound"}]}]] |
| allow votes | true |
| percent hbd | 10000 |
| max accepted payout | 1000000.000 HBD |
| allow curation rewards | true |
| Transaction Info | Block #25940339/Trx 1a59fe67115750dbd3c4db590bda8a6dfb19f922 |
View Raw JSON Data
{
"op": [
"comment_options",
{
"author": "acidsound",
"permlink": "8vpzv0im",
"extensions": [
[
0,
{
"beneficiaries": [
{
"weight": 2500,
"account": "acidsound"
}
]
}
]
],
"allow_votes": true,
"percent_hbd": 10000,
"max_accepted_payout": "1000000.000 HBD",
"allow_curation_rewards": true
}
],
"block": 25940339,
"trx_id": "1a59fe67115750dbd3c4db590bda8a6dfb19f922",
"op_in_trx": 1,
"timestamp": "2018-09-14T02:10:42",
"virtual_op": false,
"trx_in_block": 8
}2018/09/14 02:10:42
2018/09/14 02:10:42
| body | <center><a href='http://localhost:3000/#!/v/acidsound/8vpzv0im'><img src='https://ipfs.io/ipfs/QmezHXx9HR7WnMveuXbmP8Qi2NQfctVyfe8Tbyx3gz5vYB'></a></center><hr> haircust costs is just 5 bucks! <hr><a href='http://localhost:3000/#!/v/acidsound/8vpzv0im'> ▶️ CTube</a><br /> |
| title | the cheapest hairshop in gangnam. |
| author | acidsound |
| permlink | 8vpzv0im |
| json metadata | {"video":{"info":{"title":"the cheapest hairshop in gangnam.","snaphash":"QmXyaZEhZ39vAjLmT5zcVfD9WVQaxLzKgwzzNgPL1mQpa4","author":"acidsound","permlink":"8vpzv0im","streamId":"CH9f4b886905124a8e80fd457d46e2deab","livestream":true},"content":{"description":"haircust costs is just 5 bucks!","tags":["gangnam"]}},"tags":["gangnam","ctv"],"app":"ctube/0.8"} |
| parent author | |
| parent permlink | gangnam |
| Transaction Info | Block #25940339/Trx 1a59fe67115750dbd3c4db590bda8a6dfb19f922 |
View Raw JSON Data
{
"op": [
"comment",
{
"body": "<center><a href='http://localhost:3000/#!/v/acidsound/8vpzv0im'><img src='https://ipfs.io/ipfs/QmezHXx9HR7WnMveuXbmP8Qi2NQfctVyfe8Tbyx3gz5vYB'></a></center><hr>\n\nhaircust costs is just 5 bucks!\n\n<hr><a href='http://localhost:3000/#!/v/acidsound/8vpzv0im'> ▶️ CTube</a><br />",
"title": "the cheapest hairshop in gangnam.",
"author": "acidsound",
"permlink": "8vpzv0im",
"json_metadata": "{\"video\":{\"info\":{\"title\":\"the cheapest hairshop in gangnam.\",\"snaphash\":\"QmXyaZEhZ39vAjLmT5zcVfD9WVQaxLzKgwzzNgPL1mQpa4\",\"author\":\"acidsound\",\"permlink\":\"8vpzv0im\",\"streamId\":\"CH9f4b886905124a8e80fd457d46e2deab\",\"livestream\":true},\"content\":{\"description\":\"haircust costs is just 5 bucks!\",\"tags\":[\"gangnam\"]}},\"tags\":[\"gangnam\",\"ctv\"],\"app\":\"ctube/0.8\"}",
"parent_author": "",
"parent_permlink": "gangnam"
}
],
"block": 25940339,
"trx_id": "1a59fe67115750dbd3c4db590bda8a6dfb19f922",
"op_in_trx": 0,
"timestamp": "2018-09-14T02:10:42",
"virtual_op": false,
"trx_in_block": 8
}2018/09/13 11:06:54
2018/09/13 11:06:54
| author | acidsound |
| permlink | pnsheuf4 |
| Transaction Info | Block #25922269/Virtual Operation 4294967295:3 |
View Raw JSON Data
{
"op": [
"comment_payout_update",
{
"author": "acidsound",
"permlink": "pnsheuf4"
}
],
"block": 25922269,
"trx_id": "0000000000000000000000000000000000000000",
"op_in_trx": 3,
"timestamp": "2018-09-13T11:06:54",
"virtual_op": true,
"trx_in_block": 4294967295
}nfceffective vote applied for @acidsound / d65fm8r32018/09/12 08:51:51
nfceffective vote applied for @acidsound / d65fm8r3
2018/09/12 08:51:51
| voter | nfc |
| author | acidsound |
| weight | 29832 |
| rshares | 3448218154 |
| permlink | d65fm8r3 |
| pending payout | 0.003 HBD |
| total vote weight | 59075 |
| Transaction Info | Block #25890782/Trx d47f23384ce1f4c99de18b3084cc1a0f190831a4 |
View Raw JSON Data
{
"op": [
"effective_comment_vote",
{
"voter": "nfc",
"author": "acidsound",
"weight": 29832,
"rshares": 3448218154,
"permlink": "d65fm8r3",
"pending_payout": "0.003 HBD",
"total_vote_weight": 59075
}
],
"block": 25890782,
"trx_id": "d47f23384ce1f4c99de18b3084cc1a0f190831a4",
"op_in_trx": 1,
"timestamp": "2018-09-12T08:51:51",
"virtual_op": true,
"trx_in_block": 6
}nfcupvoted (1.00%) @acidsound / d65fm8r32018/09/12 08:51:51
nfcupvoted (1.00%) @acidsound / d65fm8r3
2018/09/12 08:51:51
| voter | nfc |
| author | acidsound |
| weight | 100 (1.00%) |
| permlink | d65fm8r3 |
| Transaction Info | Block #25890782/Trx d47f23384ce1f4c99de18b3084cc1a0f190831a4 |
View Raw JSON Data
{
"op": [
"vote",
{
"voter": "nfc",
"author": "acidsound",
"weight": 100,
"permlink": "d65fm8r3"
}
],
"block": 25890782,
"trx_id": "d47f23384ce1f4c99de18b3084cc1a0f190831a4",
"op_in_trx": 0,
"timestamp": "2018-09-12T08:51:51",
"virtual_op": false,
"trx_in_block": 6
}Manabar
Voting Power100.00%
Downvote Power100.00%
Resource Credits100.00%
Reputation Progress0.00%
{
"voting_manabar": {
"current_mana": 35573672319,
"last_update_time": 1581345330
},
"downvote_manabar": {
"current_mana": 9447552822,
"last_update_time": 1581345330
},
"rc_account": {
"account": "acidsound",
"rc_manabar": {
"current_mana": 39421699458,
"last_update_time": 1581345330
},
"max_rc_creation_adjustment": {
"amount": "2020748973",
"precision": 6,
"nai": "@@000000037"
},
"max_rc": 39810960264,
"delegated_rc": 0,
"received_delegated_rc": 0
}
}Account Metadata
| POSTING JSON METADATA | |
| profile | {"profile_image":"https://gravatar.com/avatar/c1f9e3fc81c451788df421e46fda5c21?size=400","name":"acidsound","about":"function과 reactive를 좋아하는 플루티스트"} |
| JSON METADATA | |
| profile | {"profile_image":"https://gravatar.com/avatar/c1f9e3fc81c451788df421e46fda5c21?size=400","name":"acidsound","about":"function과 reactive를 좋아하는 플루티스트"} |
{
"posting_json_metadata": {
"profile": {
"profile_image": "https://gravatar.com/avatar/c1f9e3fc81c451788df421e46fda5c21?size=400",
"name": "acidsound",
"about": "function과 reactive를 좋아하는 플루티스트"
}
},
"json_metadata": {
"profile": {
"profile_image": "https://gravatar.com/avatar/c1f9e3fc81c451788df421e46fda5c21?size=400",
"name": "acidsound",
"about": "function과 reactive를 좋아하는 플루티스트"
}
}
}Auth Keys
Owner
Single Signature
Public Keys
STM5q6WPcZpvAvi6fLUmFbusAb7QL8LQniqjk71N6UpsFHHT56p7C1/1
Active
Single Signature
Public Keys
STM8HADVNSA94yRJ8b54Jrw5krBkDJQrmLcjmqw3nDW8tnis4LbY51/1
Posting
Single Signature
Public Keys
STM5vtTJdVuVcZetoHAsLatsv8y8foagwqLdPpbCCATzWXeJni9YG1/1
Memo
STM82LaqLJ2DqX13NiYEFAucd1XVyHchG879nMYfXajBEgYkfJAfQ
{
"owner": {
"account_auths": [],
"key_auths": [
[
"STM5q6WPcZpvAvi6fLUmFbusAb7QL8LQniqjk71N6UpsFHHT56p7C",
1
]
],
"weight_threshold": 1
},
"active": {
"account_auths": [],
"key_auths": [
[
"STM8HADVNSA94yRJ8b54Jrw5krBkDJQrmLcjmqw3nDW8tnis4LbY5",
1
]
],
"weight_threshold": 1
},
"posting": {
"account_auths": [
[
"busy.app",
1
],
[
"ctube.app",
1
],
[
"dlive.app",
1
],
[
"drugwars.app",
1
],
[
"dtube.app",
1
]
],
"key_auths": [
[
"STM5vtTJdVuVcZetoHAsLatsv8y8foagwqLdPpbCCATzWXeJni9YG",
1
]
],
"weight_threshold": 1
},
"memo": "STM82LaqLJ2DqX13NiYEFAucd1XVyHchG879nMYfXajBEgYkfJAfQ"
}Witness Votes
0 / 30
No active witness votes.
[]