Автор: Линь Гуаньхун / Призраки под рукой
пролог:
路印协议
Функции очень многочисленны и мощны, и в этой статье проводится только анализ начального уровня.
Для теоретической части, пожалуйста, внимательно прочитайте его технический документ.GitHub.com/loop ring/ Я тоже…
Фактическая часть кода:GitHub.com/кольцо цикла/горячее…
содержание
- Протокол закольцовывания
- обычно используется в
- эффект
- компоненты модуля
- Процесс сделки
- Код основной бизнес-логики
-
relay
Обзор исходного кода
路印协议
- короткое имя
Loopring
- и
0x
,Kyber
То же самое, это блокчейн-приложение去中心化交易协议
Во-первых, в соглашении уточняется, что поведение при его использовании для проведения сделок купли-продажи должно осуществляться в соответствии с предусмотренным им режимом. - Описанный с процессуальной точки зрения, это
Go语言
Написанное программное обеспечение с открытым исходным кодом, которое можно применять к блокчейну. - Также обратите внимание, что его нет в блокчейн-приложениях.
智能合约
, читатель обращает внимание на различие этих двух понятий.
обычно используется в
- обмен виртуальной валюты,
交易所
Есть следующие примеры- MtGox
- Bitfinex
- Хуоби
- OKEX
- ...
эффект
- Решить ряд проблем, существующих в централизованной торговле
- отсутствие безопасности
- Биржа сохраняет закрытый ключ пользователя, который был украден после хакерской атаки.
- Для проявления требуется одобрение биржи.Представьте, если бы сотрудники биржи сбежали с деньгами или вдруг закрылись
- отсутствие прозрачности
- Покупка и продажа пользователей заменены централизованными биржами, а внутренние специфические процессы держатся в секрете.
- Пользовательские активы могут быть использованы в качестве сторонних инвестиций
- отсутствие ликвидности
- Биржи с большим объемом торгов могут стать монополистами рынка.
- Даже после серьезной аварии другим пользователям приходится продолжать торговать на бирже из-за их огромной доли рынка.
- отсутствие безопасности
- Некоторые проблемы оптимизации существующих транзакций диалекта районного центра
- отсутствие единых стандартов
- плохая ликвидность
- Сеть вещания малых заказов
- Скорость обновления таблицы заказов низкая после завершения транзакции
- проблемы с производительностью
- Вызывает высокую комиссию за выполнение кода
- задержка питтинга
- Изменение/отмена заказов стоит дорого
компоненты модуля
- Программное обеспечение кошелька, поддерживающее отправку запросов в сеть Loopring.
- APP
- WEB
- Программное обеспечение Loopring Relay --
Relay
- Циклический смарт-контракт блокчейна --
LPSC
- Релейная сеть Loopring, управляемая несколькими
路印中继软件
сетевых узлов - Цепочка альянсов Loopring, организованная
LPSC
блокчейн
Процесс сделки
Сравните картинку выше с 6 шагами.说明
и代码核心业务逻辑
1. Авторизация соглашения
- Пользователь Y хочет торговать токенами, поэтому разрешает LPSC продать 9 токенов B. Это действие не замораживает токены пользователя. Во время обработки заказа пользователи по-прежнему могут свободно распоряжаться токенами.
-
代码调用逻辑
Да: кошелек для определенного блокчейна, такого как Ethereum.公有链
положить началоjson-rpc请求
, по запросу合约地址address
и合约ABI
После того, как информация находит соответствующий контракт LPSC,methodName
Найдите соответствующие методы интерфейса, которые, конечно же, соответствуют стандарту ERC20. Запросить авторизацию на продажу 9 токенов B для учетной записи Y.
2. Создание заказа
-
В приложении кошелька или веб-приложении он отображается сетевым посредником, таким как сторонний интерфейс API.
https://api.coinmarketcap.com
поставка Текущий обменный курс и таблица ордеров между токеном B и токеном C. Основываясь на этой информации, пользователи настраивают свои собственные покупки и продажи токенов и связанные с ними количества, например: продажа10ETH
,Купить50EOS
. Затем создайте этот запрос заказа с дополнительной информацией в заказе. Окончательный заказ шифруется закрытым ключом пользователя Y, то есть подписывается и отправляется中继点软件 --- relay
-
代码调用逻辑
Да: клиент кошелька может использовать Http-запрос для вызова стороннего API-интерфейса или использовать другие методы для полученияticker--24小时市场变化统计数据
После объединения с информацией о цене каждого токена таблица заказов и обменный курс отображаются в сочетании через интерфейс пользовательского интерфейса. После того, как пользователь настроил свою собственную информацию о заказе и подписалjosn-rpc
запроситьrelay
Инициировать запрос заказа. -
Этапы подписания заказа
- Документация
- использовать
Keccak-256
Алгоритм хеширует этот массив байтов, чтобы получить хэш порядка - Алгоритм подписи Secp256k1 подписывает полученный хеш, чтобы получить Sig.
- 0–32 бита Sig преобразуются в шестнадцатеричные строки и присваиваются r порядка.
- 32-64 бита Sig преобразуются в шестнадцатеричные строки и присваиваются s of Order.
- 64 бита Sig плюс 27 преобразуются в v целочисленного порядка.
3. Заказать трансляцию
-
Кошелек отправляет ордер и его подпись на один или несколько ретрансляторов, а ретранслятор затем обновляет свою таблицу публичных ордеров. Протокол Loopring не ограничивает структуру таблицы заказов, допуская модель «первым пришел, первым обслужен»; ретранслятор может сам выбирать структуру таблицы заказов.
-
代码调用逻辑
Да: клиент отправляет один или несколькоrelay
Отправитьorder request
Задний,relay
После получения заказа, а затем друг к другуrelay
Вещание, технический пункт вещанияrelay
в исходном кодеgateway
Часть его можно увидеть с помощьюIPFS--点对点的分布式版本文件系统
Технологии. то этиrelay
Нажмите на них, чтобы составить то, что сказано выше路印中继网
. Затем каждыйrelay
Сделать соответствующие формы заказаrefresh
, что обеспечивает единство. Дизайн таблицы настраивается, например, поля, выбор механизма базы данных и т. д.
4. Разделение ликвидности
- Эта часть была подчинена Межвещательной части третьего пункта.
- Кроме того, два дополнительных пункта
- Узлы имеют право выбирать, взаимодействовать ли и каким образом, и мы можем вводить различные ограничения, изменяя исходный код.
- В этой части есть ключевой момент - проектирование алгоритма обновления таблицы после приема трансляции, как добиться
高速处理
и杜绝误差回滚
5. Сопоставление цикла (сопоставление порядка)
-
Кольцевые майнеры сопоставляют несколько заказов и удовлетворяют часть или всю сумму заказа по обменному курсу, равному или лучше, чем обменный курс, указанный пользователем. Причина, по которой Loopring может гарантировать высокую ликвидность между любой торговой парой, во многом связана с Ring Miners. Если скорость транзакции выше, чем ставка пользователя Y, все заказы в цикле могут разделить прибыль. В качестве вознаграждения кольцевые майнеры могут собирать часть прибыли (разделять прибыль и одновременно платить LRx пользователю) или взимать первоначальную комиссию LRx.
-
Первоначальная плата
LRx
задается клиентом при создании заказа -
Математический символ петли
-
环路矿工撮合多笔订单,以等同或优于用户开出的汇率满足部分或全部订单数额
. Его выражение: Ri->j * Rj->i >= 1 - Кроме того, по определенному ордеру торгуется его часть. Например, если вы продаете 10А, чтобы купить 2В, и вы продаете 4А, то по умолчанию должна быть покупка (2/5)В. так как. Курс обмена заказа постоянный
Если ордер не исполнен полностью: Ri->j * Rj->i = 1, пропорциональный курс для частичной продажи и покупки равен
原始的兑换率
. 10/2=4/год
-
-
代码调用逻辑
Да:miner
часть кода иrelay
в том же проекте. существуетrelay
После обработки заказа,miner
Я перейду к форме заказа, чтобы получить заказ на соответствие. Сформировано оптимальное кольцо, т. е. порядок успешно подобран,miner
Этот слой будет выполнять соответствующие математические операции.
6. Проверка и расчет
- Эта часть
LPSC
обработанный.- После того, как LPSC получает кольцо заказов, он выполняет несколько проверок для проверки данных, предоставленных майнерами кольца, таких как подписи всех сторон.
- Определяет, может ли кольцо ордера быть частично или полностью рассчитано (в зависимости от обменного курса кольца ордера и баланса токенов в кошельке пользователя).
- Если проверки соответствуют стандартам, LPSC пройдет
原子操作
Токены передаются пользователям, а комиссионные выплачиваются кольцевым майнерам и кошелькам. - Если LPSC обнаружит, что баланс пользователя Y недостаточен, он уменьшит сумму заказа.
- Как только на адрес будет зачислено достаточно средств, заказ автоматически вернется к первоначальной сумме. Отмена заказа требует односторонней ручной операции и необратима.
- Адрес в указанном выше адресе депозита относится к адресу учетной записи пользователя в блокчейне.
-
代码调用逻辑
Да:relay
Пучокminer
Данные цикла , как и в первом пункте, передаются черезjson-rpc
запрос в публичную сетьLPSC
договор и пусть он обрабатывается.
relay
Обзор исходного кода
Насколько я проанализировал последниеrelay
исходный код, который внутренне в настоящее время основан наETH
Публичная сеть как первая блокчейн-платформа для разработки. внутреннее использование以太坊
В исходном пакете Go есть множество структур методов,json-rpc
Наиболее часто вызываемые команды:Geth
из.
Возможно, учитывая зрелость и популярность ETH, ETH был выбран в качестве первой платформы блокчейна для разработки. Но протокол Loopring не предназначен для ETH, его можно реализовать на нескольких разнородных блокчейнах, соответствующих условиям. Последующие оценки будут учитывать развитие общедоступных сетей, таких как EOS и ETC.
запись программы
Принят режим cli, то есть предусмотрен локальный запрос командной строки. Также предоставляются внешние API.
--relay
--|--cmd
--|--|--lrc
--|--|--|--main.go
func main() {
app := utils.NewApp()
app.Action = startNode // 启动一个中继节点
...
}
Инициализация и запуск узла
func startNode(ctx *cli.Context) error {
globalConfig := utils.SetGlobalConfig(ctx) // 读取配置文件并初始化
// 日志系统初始化
// 对系统中断和程序被杀死事件信号的注册
n = node.NewNode(logger, globalConfig) // 初始化节点
//...
n.Start() // 启动节点
//...
return nil
}
Файл конфигурации находится по адресу
--relay
--|--config
--|--|--relay.toml
--|--|--其它
relay.toml
Существует множество внутренних настраиваемых элементов, таких как база данных жесткого хранилища.MySQL
Настройки информации о конфигурации и т. д.
Инициализируйте узел, см. комментарии к следующему коду для введения каждой части
func NewNode(logger *zap.Logger, globalConfig *config.GlobalConfig) *Node {
// ...
// register
n.registerMysql() // lgh:初始化数据库引擎句柄和创建对应的表格,使用了 gorm 框架
cache.NewCache(n.globalConfig.Redis) // lgh:初始化Redis,内存存储三方框架
util.Initialize(n.globalConfig.Market) // lgh:设置从 json 文件导入代币信息,和市场
n.registerMarketCap() // lgh: 初始化货币市值信息,去网络同步
n.registerAccessor() // lgh: 初始化指定合约的ABI和通过json-rpc请求eth_call去以太坊获取它们的地址,以及启动了定时任务同步本地区块数目,仅数目
n.registerUserManager() // lgh: 初始化用户白名单相关操作,内存缓存部分基于 go-cache 库,以及启动了定时任务更新白名单列表
n.registerOrderManager() // lgh: 初始化订单相关配置,含内存缓存-redis,以及系列的订单事件监听者,如cancel,submit,newOrder 等
n.registerAccountManager() // lgh: 初始化账号管理实例的一些简单参数。内部主要是和订单管理者一样,拥有用户交易动作事件监听者,例如转账,确认等
n.registerGateway() // lgh:初始化了系列的过滤规则,包含订单请求规则等。以及 GatewayNewOrder 新订单事件的订阅
n.registerCrypto(nil) // lgh: 初始化加密器,目前主要是Keccak-256
if "relay" == globalConfig.Mode {
n.registerRelayNode()
} else if "miner" == globalConfig.Mode {
n.registerMineNode()
} else {
n.registerMineNode()
n.registerRelayNode()
}
return n
}
func (n *Node) registerRelayNode() {
n.relayNode = &RelayNode{}
n.registerExtractor()
n.registerTransactionManager() // lgh:事务管理器
n.registerTrendManager() // lgh: 趋势数据管理器,市场变化趋势信息
n.registerTickerCollector() // lgh: 负责统计24小时市场变化统计数据。目前支持的平台有OKEX,币安
n.registerWalletService() // lgh: 初始化钱包服务实例
n.registerJsonRpcService()// lgh: 初始化 json-rpc 端口和绑定钱包WalletServiceHandler,start 的时候启动服务
n.registerWebsocketService() // lgh: 初始化 webSocket
n.registerSocketIOService()
txmanager.NewTxView(n.rdsService)
}
func (n *Node) registerMineNode() {
n.mineNode = &MineNode{}
ks := keystore.NewKeyStore(n.globalConfig.Keystore.Keydir, keystore.StandardScryptN, keystore.StandardScryptP)
n.registerCrypto(ks)
n.registerMiner()
}
из вышеперечисленногоregister
Нажмите, чтобы начать анализ. Есть следующие выводы
- Общий,
relay
Режим связи внутреннего кода основан на:事件订阅--事件接收--事件处理
из. -
relay
В качестве базы данных жесткого хранилища используется распределенная база данных Mysql, которая используется в коде.gorm
Рамка. существуетregisterMysql
Созданные формы и т.д. - Есть два набора памяти
- на основе
Redis
- на основе
go-cache
библиотека
- на основе
- В информации об импортном токене и в разделе информации о рыночной стоимости есть
问题点
: в файле конфигурации市场市值
Сторонний интерфейс для сбора данныхcoinmarketcap
опубликовала заявление на своем официальном сайте,v1
Версия API будет отключена 30 ноября этого года, так что,relay
Следующее в файле конфигурации по умолчанию здесь необходимо изменить наv2
версия.
[market_cap]
base_url = "https://api.coinmarketcap.com/v1/ticker/?limit=0&convert=%s"
currency = "USD"
duration = 5
is_sync = false
-
OrderManager
иAccountManager
зарегистрирован вEvent
событие, точка, которая в основном срабатывает,socketio.go
, соответствующий упомянутому вышеgateway
модуль, отвечающий за получениеIPFS
трансляция сообщений. После того, как он будет получен, он будет снова передан для запуска обработки события.--relay --|--gateway --|--|--socketio.go func (so *SocketIOServiceImpl) broadcastTrades(input eventemitter.EventData) (err error) { // ... v.Emit(eventKeyTrades+EventPostfixRes, respMap[fillKey]) // ... }
-
Шаги запуска события нового заказа разделены на два уровня.
-
gateway.go
внутриeventemitter.GatewayNewOrder
Зависит отIPFS
распределение -
OrderManager
внутриeventemitter.NewOrder
- Зависит от
gateway.go
получилаGatewayNewOrder
распространен позже. - Звонок клиента
WalletService
APISubmitOrder
пост-триггер
- Зависит от
-
-
relay
из节点模式
Есть 3 вида-
одиночный запуск
relay
узел ретрансляции -
одиночный запуск
miner
узел майнера -
Двойная загрузка, которая является формой по умолчанию
if "relay" == globalConfig.Mode { n.registerRelayNode() } else if "miner" == globalConfig.Mode { n.registerMineNode() } else { n.registerMineNode() n.registerRelayNode() }
-
-
relay--中继节点
API, предоставляемый клиенту, в основномWalletService
кошелек. Имя префиксного метода:loopring
-
Поддержка вызова формата json-rpc
-
Просто позвоните в форме Http-GET & POST
func (j *JsonrpcServiceImpl) Start() { handler := rpc.NewServer() if err := handler.RegisterName("loopring", j.walletService); err != nil { fmt.Println(err) return } var ( listener net.Listener err error ) if listener, err = net.Listen("tcp", ":"+j.port); err != nil { return } //httpServer := rpc.NewHTTPServer([]string{"*"}, handler) httpServer := &http.Server{Handler: newCorsHandler(handler, []string{"*"})} //httpServer.Handler = newCorsHandler(handler, []string{"*"}) go httpServer.Serve(listener) log.Info(fmt.Sprintf("HTTP endpoint opened on " + j.port)) return }
-
-
Miner--矿工节点
, в основном обеспечивает функцию сопоставления циклов заказов, которую можно настроить с помощью следующих частей.[miner] ringMaxLength = 4 // 最大的环个数 name = "miner1" rate_ratio_cvs_threshold = 1000000000000000 subsidy = 1.0 walletSplit = 0.8 minGasLimit = 1000000000 maxGasLimit = 100000000000 // 邮费最大值 feeReceipt = "0x750aD4351bB728ceC7d639A9511F9D6488f1E259" [[miner.normal_miners]] address = "0x750aD4351bB728ceC7d639A9511F9D6488f1E259" maxPendingTtl = 40 maxPendingCount = 20 gasPriceLimit = 10000000000 [miner.TimingMatcher] round_orders_count=2 duration = 10000 // 触发一次撮合动作的毫秒数 delayed_number = 10000 max_cache_rounds_length = 1000 lag_for_clean_submit_cache_blocks = 200 reserved_submit_time = 45 max_sumit_failed_count = 3
-
Запуск узла майнера делится на две части:
- Сопоставитель, отвечающий за сопоставление заказов
- Отправитель, ответственный за отправку и другую обработку результатов заказа
func (minerInstance *Miner) Start() { minerInstance.matcher.Start() minerInstance.submitter.start() }
-
miner
собственный计费者
. существует匹配者matcher
Время отordermanager
Вытащить n предметов изorder
Данные сопоставляются в цикле, и если он зациклен, он вызывается вызовомevaluator
Рассчитать стоимость и отправитьsubmitter
Сделать коммит в Ethereumevaluator := miner.NewEvaluator(n.marketCapProvider, n.globalConfig.Miner)
-
сопоставитель
matcher.Start()
func (matcher *TimingMatcher) Start() { matcher.listenSubmitEvent() // lgh: 注册且监听 Miner_RingSubmitResult 事件,提交成功或失败或unknown 后,都从内存缓存中删除该环 matcher.listenOrderReady() // lgh: 定时器,每隔十秒,进行以太坊,即Geth同步的区块数和 relay 本地数据库fork是false的区块数进行对比,来控制匹配这 matcher 是否准备好,能够进行匹配 matcher.listenTimingRound() // lgh: 开始定时进行环的撮合,受上面的 orderReady 影响 matcher.cleanMissedCache() // lgh: 清除上一次程序退出前的错误内存缓存 }
-
Geth
количество синхронизированных блоков иrelay
локальная база данныхfork是false
количество блоков для сравнения
if err = ethaccessor.BlockNumber(ðBlockNumber); nil == err { var block *dao.Block // s.db.Order("create_time desc").Where("fork = ?", false).First(&block).Error if block, err = matcher.db.FindLatestBlock(); nil == err { block.BlockNumber, ethBlockNumber.Int64()) if ethBlockNumber.Int64() > (block.BlockNumber + matcher.lagBlocks) { matcher.isOrdersReady = false } else { matcher.isOrdersReady = true } } } ...
-
matcher.isOrdersReady
контроль撮合的开始
if !matcher.isOrdersReady { return } ... m.match() ...
-
TimingMatcher.match
метод в целом订单撮合
Основной. После успешного сопоставления он отправитeventemitter.Miner_NewRing
Новое событие на ринге, расскажите подписчикам, что матч прошел успешно
-
-
Представленный
submitter.start()
. Отправитель, есть очень важный шаг: после подписки и прослушиванияMiner_NewRing
событие, то提交到以太坊
, а затем обновите локальный环数据表
. код показывает, как показано ниже// listenNewRings() txHash, status, err1 := submitter.submitRing(ringState) // 提交到以太坊 ... submitter.submitResult(...) // 触发本地的 update
func (submitter *RingSubmitter) submitRing(...) { ... if nil == err { txHashStr := "0x" // ethaccessor.SignAndSendTransaction 提交函数 txHashStr, err = ethaccessor.SignAndSendTransaction(ringSubmitInfo.Miner, ringSubmitInfo.ProtocolAddress, ringSubmitInfo.ProtocolGas, ringSubmitInfo.ProtocolGasPrice, nil, ringSubmitInfo.ProtocolData, false) ... txHash = common.HexToHash(txHashStr) } ... }
-
На данный момент у нас есть общая концепция. по сравнению с вышеперечисленным交易流程
рисунок. Чтобы инициировать заказ от клиента, обаrelay
После обработки он, наконец, отправляется в блокчейн (например, в публичную сеть Ethereum) до тех пор, пока не будет завершена окончательная транзакция.relay
Каждый модуль в исходном коде отвечает за свою собственную ответственность.
Relay
да钱包
и路印协议
между桥接
, вверх и钱包
приклад, вниз иMiner
стыковка. давать钱包
предоставить API дляMiner
Обеспечить заказы, поддерживать пул заказов внутри.
miner
Соответствие заказов с одной стороны, а с другой стороныLPSC
взаимодействовать. иLPSC
Он взаимодействует с публичной сетью, в которой находится.