您正在查看: 2021年9月

多部门重拳整治虚拟币炒作 “挖矿”活动被彻底清理

对虚拟币的整治再次升级。

9月24日,人民银行等十部门再发新规整治“虚拟币炒作”,明确了虚拟币相关业务活动属于非法金融活动。同日,国家发改委等十一部门联合发文,整治虚拟币“挖矿”,要求严禁新增项目投资建设、加快存量项目有序退出。

虚拟币市场闻声下跌,比特币家园数据显示,比特币价格当日下跌超4%,以太币跌超7%。星火矿池宣布配合最新的行业监管政策,将关闭中国大陆境内矿池服务。25日,虚拟币交易平台火币、去中心化钱包TokenPocket也停止对国内用户提供部分服务。BHEX、BiONE等小交易平台宣布永久关闭。

业内专家普遍认为,新规出台再次表明了监管部门对虚拟币强监管的高压态度,并对此前没有明确规定的定价服务、信息中介等“灰色地带”进行了厘清,杜绝了炒币者的幻想,防范了相关金融风险。

虚拟币相关业务为“非法金融活动”
9月24日,人民银行官网发布了《关于进一步防范和处置虚拟货币交易炒作风险的通知》(以下简称《通知》)。

《通知》提出构建多维度、多层次的风险防范和处置体系,要求金融机构和非银行支付机构不得为虚拟币相关业务活动提供服务;加强对虚拟币相关的市场主体登记和广告管理;加强对虚拟币相关的互联网信息内容和接入管理等。

“与以往的政策规范相比,《通知》在明确虚拟币和相关业务活动本质属性方面提出了新的定义。”中国银行法学研究会理事肖飒表示,一是直接挑明USDT(泰达币)属于虚拟币,不受我国法律保护;二是为虚拟币提供“定价服务”也属于违法,未来会被取缔;三是虚拟币交易“信息中介”模式,不再是灰色地带,已归于非法范畴;四是境外交易平台的境内人员,不能逃避法律责任;五是涉虚拟币投资交易的合同无效,理由是违反公序良俗。

北京链通律师事务所主任丁飞鹏在接受《证券日报》记者采访时表示,《通知》首次明确虚拟币相关业务活动的性质,目前主流虚拟币交易平台的“场内币币交易”和“场外OTC”的组合模式在定性上已经没有争议了,虚拟币之间的兑换业务或为国内用户提供这种兑换业务已经被明确定义为“非法金融活动”。

丁飞鹏进一步表示,《通知》发布前,司法实践中对虚拟币的性质的定义各不相同,有的地方认为属于“虚拟商品”“民间金融资产”,应当受到法律的平等保护;有的地方认为投资虚拟币属于非法,不受法律保护。《通知》发布后,司法机关可以“违背公序良俗”为由,宣布相关民事法律行为无效,由此引发的损失由参与者自行承担。

工信部工业互联网区块链重大项目评审专家、中国移动通信联合会区块链专业委员会主任委员陈晓华对记者表示,《通知》提出,从部委协同联动、强化属地落实、全方位监测预警,各省建立信息共享和快速反应机制等方面进行监管,监管力度更大、范围更广、不留死角,体现了建立常态化工作机制,始终保持对虚拟币交易的高压打击态势。

整治虚拟币“挖矿”严禁增量、妥处存量
同日,国家发改委等十一部门出台《关于整治虚拟货币“挖矿”活动的通知》(以下简称《通知》)。

《通知》指出,按照“严密监测、严防风险、严禁增量、妥处存量”的总体思路,充分发挥各地区、各部门合力,加强虚拟币“挖矿”活动上下游全产业链监管,严禁新增虚拟币“挖矿”项目,加快存量项目有序退出。

“虚拟币‘挖矿’活动能耗大、耗电高,其盲目无序的发展给节能减排造成不利影响。”宝新金融首席经济学家郑磊对《证券日报》记者表示,在电煤价格高居不下,生活和生产用电受到碳排放考核影响的情况下,各地更应加快清退虚拟币“挖矿”项目。

深圳市信息服务业区块链协会会长郑定向对《证券日报》记者表示,目前,虚拟币挖矿造成了能源的过度消耗,增加了碳排放,并且矿机的快速更换会产生更多的电子垃圾处理排放,这与我国碳中和发展理念背道而驰,不利于实现双碳目标。

具体来看,在全面梳理排查虚拟币“挖矿”项目方面,《通知》提出梳理排查存量项目,保证本地虚拟币“挖矿”排查工作不留空白;梳理排查在建新增项目;加强异常用电监测分析。

事实上,今年6月份,内蒙古、四川、青海、新疆等地方政府积极行动,清退虚拟币“挖矿”企业,无论是火电为主还是水电为主的“挖矿”企业均遭清理整顿。9月份,河北、甘肃再次针对虚拟币“挖矿”和交易行为部署专项整治行动。并提出后续将进行常态化监管,常态化开展清查虚拟币矿机“挖矿”、违约用电和窃电等工作。

肖飒称,《通知》明确把“挖矿”活动列为淘汰类产业,并不给予任何支持。严禁以数据中心名义开展虚拟币“挖矿”活动。要求地方不要给“挖矿”企业财税支持和金融服务,从资金来源上打击“挖矿”企业。

丁飞鹏称,“挖矿”企业对于电价极为敏感,《通知》明确将虚拟币“挖矿”项目纳入“淘汰类”企业电价,实行加价。明确禁止虚拟币“挖矿”项目参与电力市场,直接切断了一些虚拟币“挖矿”项目的退路。

HECO节点升级v1.2.0注意事项

  1. 默认会开启snapshot加速结构,首次生成过程会非常慢,并且(若节点性能较差)可能导致节点无法实时跟上最新区块高度。建议临时升级服务器配置
  2. 节点可能遭遇 “BAD BLOCK” 问题,并导致区块停止同步。此问题由以太坊 Geth v1.10.8 引入,并已有以太坊用户报告,详见这里 https://github.com/ethereum/go-ethereum/issues/23531 及这里 https://github.com/ethereum/go-ethereum/issues/23546
    此问题跟首次生成snapshot这个过程有关,并且只是偶尔出现。主要有两种方案处理此问题:
    (1)遇到此问题时,重启节点,重启后预期就可以恢复正常并可继续同步区块;
    (2)若对此问题敏感,可以在节点启动时加入参数 “ --snapshot=false" 以禁用快照加速结构,直到此问题完全解决,再尝试开启。
  3. 新版本配置项有变更,DiscoveryURLs 已删除,取而代之的是两个配置项:EthDiscoveryURLs 和 SnapDiscoveryURLs。若之前有提供 DiscoveryURLs,建议可直接删掉该项。

验证BTC地址是否有效

validateaddress "address"

Return information about the given bitcoin address.

Arguments:
1. address    (string, required) The bitcoin address to validate

Result:
{
  "isvalid" : true|false,       (boolean) If the address is valid or not. If not, this is the only property returned.
  "address" : "address",        (string) The bitcoin address validated
  "scriptPubKey" : "hex",       (string) The hex-encoded scriptPubKey generated by the address
  "isscript" : true|false,      (boolean) If the key is a script
  "iswitness" : true|false,     (boolean) If the address is a witness address
  "witness_version" : version   (numeric, optional) The version number of the witness program
  "witness_program" : "hex"     (string, optional) The hex value of the witness program
}

Examples:
> bitcoin-cli validateaddress "1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc"
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "validateaddress", "params": ["1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc"] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/

https://bitcoincore.org/en/doc/0.18.0/rpc/util/validateaddress/

以太坊合约中是否可以获取交易hash?

答案:不能
txhash 是keccak256(signedTransaction).
此 keccak256 函数可用作 Solidity 函数 http://solidity.readthedocs.io/en/v0.4.21/units-and-global-variables.html

所以你需要构造,signedTransaction因为这个值没有暴露于可靠性,参见。https://stackoverflow.com/questions/49803424/how-can-we-access-rlp-encoded-signed-raw-transaction-in-solidity

signedTransaction 需要的参数是

  1. nonce
  2. gas price
  3. gas limit
  4. to
  5. value in wei
  6. data
  7. ecdsaV
  8. ecdsaR
  9. ecdsaS

值 3 不是直接可用的,但您可以在代码执行的任何时候获取当前剩余的 gas,并从中计算出执行开始后可用的气体量。值 1、7、8 和 9(nonce 和签名值)不能使用solidity,也不能使用汇编代码(可以在solidity 源代码文件中内联编写)。所以很遗憾该问题无法解决。

https://ethereum.stackexchange.com/questions/45648/how-to-calculate-the-assigned-txhash-of-a-transaction
https://github.com/ethereum/EIPs/issues/901

以太坊索引器通过 ETH 地址获取交易列表

https://github.com/Adamant-im/ETH-transactions-storage/blob/master/ethsync.py

# Indexer for Ethereum to get transaction list by ETH address
# https://github.com/Adamant-im/ETH-transactions-storage
# 2021 ADAMANT Foundation (devs@adamant.im), Francesco Bonanno (mibofra@parrotsec.org),
# Guénolé de Cadoudal (guenoledc@yahoo.fr), Drew Wells (drew.wells00@gmail.com)
# 2020-2021 ADAMANT Foundation (devs@adamant.im): Aleksei Lebedev
# 2017-2020 ADAMANT TECH LABS LP (pr@adamant.im): Artem Brunov, Aleksei Lebedev
# v2.0

from os import environ
from web3 import Web3
from web3.middleware import geth_poa_middleware
import psycopg2
import time
import sys
import logging
#from systemd.journal import JournalHandler

# Get env variables or set to default
dbname = environ.get("DB_NAME")
startBlock = environ.get("START_BLOCK") or "1"
confirmationBlocks = environ.get("CONFIRMATIONS_BLOCK") or "0"
nodeUrl = environ.get("ETH_URL")
pollingPeriod = environ.get("PERIOD") or "20"

if dbname == None:
    print('Add postgre database in env var DB_NAME')
    exit(2)

if nodeUrl == None:
    print('Add eth url in env var ETH_URL')
    exit(2)

# Connect to Ethereum node
if nodeUrl.startswith("http"):
    web3 = Web3(Web3.HTTPProvider(nodeUrl))
if nodeUrl.startswith("ws"):
    web3 = Web3(Web3.WebsocketProvider(nodeUrl)) # "ws://publicnode:8546"
if web3 == None:
    web3 = Web3(Web3.IPCProvider(nodeUrl)) # "/home/parity/.local/share/openethereum/jsonrpc.ipc"

web3.middleware_onion.inject(geth_poa_middleware, layer=0)

# Start logger
#logger = logging.getLogger("EthIndexerLog")
logger = logging.getLogger("eth-sync")
logger.setLevel(logging.INFO)

# File logger
#lfh = logging.FileHandler("/var/log/ethindexer.log")
lfh = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
lfh.setFormatter(formatter)
logger.addHandler(lfh)

# Systemd logger, if we want to user journalctl logs
# Install systemd-python and 
# decomment "#from systemd.journal import JournalHandler" up
#ljc = JournalHandler()
#formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
#ljc.setFormatter(formatter)
#logger.addHandler(ljc)

try:
    logger.info("Trying to connect to "+ dbname)
    conn = psycopg2.connect(dbname)
    conn.autocommit = True
    logger.info("Connected to the database")
except:
    logger.error("Unable to connect to database")
    exit(1)

# Delete last block as it may be not imparted in full
cur = conn.cursor()
cur.execute('DELETE FROM public.ethtxs WHERE block = (SELECT Max(block) from public.ethtxs)')
cur.close()
conn.close()

# Wait for the node to be in sync before indexing
logger.info("Waiting Ethereum node to be in sync...")

while web3.eth.syncing != False:
    # Change with the time, in second, do you want to wait
    # before cheking again, default is 5 minutes
    time.sleep(300)

logger.info("Ethereum node is synced!")

# Adds all transactions from Ethereum block
def insertion(blockid, tr):
    time = web3.eth.getBlock(blockid)['timestamp']
    for x in range(0, tr):
        trans = web3.eth.getTransactionByBlock(blockid, x)
        # Save also transaction status, should be null if pre byzantium blocks
        status = bool(web3.eth.get_transaction_receipt(trans['hash']).status)
        txhash = trans['hash'].hex()
        value = trans['value']
        inputinfo = trans['input']
        # Check if transaction is a contract transfer
        if (value == 0 and not inputinfo.startswith('0xa9059cbb')):
            continue
        fr = trans['from']
        to = trans['to']
        gasprice = trans['gasPrice']
        gas = web3.eth.getTransactionReceipt(trans['hash'])['gasUsed']
        contract_to = ''
        contract_value = ''
        # Check if transaction is a contract transfer
        if inputinfo.startswith('0xa9059cbb'):
            contract_to = inputinfo[10:-64]
            contract_value = inputinfo[74:]
        # Correct contract transfer transaction represents '0x' + 4 bytes 'a9059cbb' + 32 bytes (64 chars) for contract address and 32 bytes for its value
        # Some buggy txs can break up Indexer, so we'll filter it
        if len(contract_to) > 128:
            logger.info('Skipping ' + str(txhash) + ' tx. Incorrect contract_to length: ' + str(len(contract_to)))
            contract_to = ''
            contract_value = ''
        cur.execute(
            'INSERT INTO public.ethtxs(time, txfrom, txto, value, gas, gasprice, block, txhash, contract_to, contract_value, status) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
            (time, fr, to, value, gas, gasprice, blockid, txhash, contract_to, contract_value, status))

# Fetch all of new (not in index) Ethereum blocks and add transactions to index
while True:
    try:
        conn = psycopg2.connect(dbname)
        conn.autocommit = True
    except:
        logger.error("Unable to connect to database")

    cur = conn.cursor()

    cur.execute('SELECT Max(block) from public.ethtxs')
    maxblockindb = cur.fetchone()[0]
    # On first start, we index transactions from a block number you indicate
    if maxblockindb is None:
        maxblockindb = int(startBlock)

    endblock = int(web3.eth.blockNumber) - int(confirmationBlocks)

    logger.info('Current best block in index: ' + str(maxblockindb) + '; in Ethereum chain: ' + str(endblock))

    for block in range(maxblockindb + 1, endblock):
        transactions = web3.eth.getBlockTransactionCount(block)
        if transactions > 0:
            insertion(block, transactions)
        else:
            logger.debug('Block ' + str(block) + ' does not contain transactions')
    cur.close()
    conn.close()
    time.sleep(int(pollingPeriod))