Занурення в технологію блокчейн: Екосистема цифровий стоматології

Представляємо другу статтю із серії «Занурення в технологію блокчейн». У цьому матеріали ви дізнаєтеся про медичне проекті Digital Dentistry Exchange, який представляє з себе екосистему цифровий стоматології.

Ми розповімо про його технологічні особливості, відповімо на найчастіші питання про смарт-контрактах і поділимося баченням команди про те, яке майбутнє у технології блокчейн.



Цикл статей «Занурення в технологію блокчейн»
1. Занурення в технологію блокчейн: Секрети EmerCoin.
2. Занурення в технологію блокчейн: Швидкі та безпечні транзакції.
3. Занурення в технологію блокчейн: Екосистема цифровий стоматології.
4. Loading…

Проблема розподілу відповідальності та підвищення якості комплексних послуг у сфері стоматології
У сучасної стоматології існує напрямок під назвою CAD/CAM (Computer Aided Design і Computer Aided Manufacturing). Воно застосовується для створення таких зуботехнічних конструкцій, як коронки, вініри або вкладки (дуже крутий вид пломб). Процес виробництва за допомогою ЕОМ складається з декількох етапів:

1. Лікар проводить підготовку зуба до встановлення зуботехнічної конструкції, знімає відбиток і формує замовлення-наряд:



2. Лікар домовляється про ціну з пацієнтом, йде передплата.

3. Відбиток сканується і виходить цифрова тривимірна модель зубів пацієнта:



4. За допомогою системи спеціалізованого проектування (САПР) на базі цієї моделі конструюється дизайн зуботехнічної конструкції з урахуванням побажань пацієнта і лікаря.

5. Після підтвердження тривимірна модель зуботехнічного вироби відправляється у фрезерний центр, де її матеріалізують з обраного матеріалу (цирконій, титан, полімер або кераміка).

6. Виріб дезінфікується і встановлюється пацієнта.



Кожен етап оплачується окремо, але якщо на одному з етапів відбувається помилка, то всі наступні етапи будуть зроблені марно, хоча вони вже оплачені. Здавалося б, виправити це просто: тестувати кожен етап і забути про проблему. Але, наприклад, труднощі виявляються на етапі установки продукту пацієнту, а попередні етапи (сканування, дизайн і фрезерування) вже оплачені. Це означає, що лікар втрачає гроші, час і нерви. Останні два пункти стосуються також і пацієнта.

Логічним рішенням є створення багатосторонніх договорів, які дозволяють розподілити відповідальність між учасниками CAD/CAM процесу. Тут з'являється величезний вибір різних стратегій виплат, наприклад:
  • лікар виплачує всім учасникам тільки при успішній установці вироби;
  • лікар виплачує учасникам по черзі при підтвердженні кожним учасником попереднього результату, можна додати страхування, репутацію і так далі.
У підсумку, угоди з кількома активними сторонами можуть бути по-різному представлені, в залежності від цього також будуть ранжируватися ціни на послуги.

Цей підхід не був реалізований раніше з кількох причин: створити такі форми угод було неможливо із-за відсутності регулятора оплат, а також з-за високої складності формулювання договорів з великою кількістю застережень.

Реалізація ідеї
Примітка: нижче представлений реальний код, написаний в рамках хакатона.

Проблему описану вище можна вирішити з допомогою смарт-контрактів: складні схеми оплат упаковуються в кнопки «accept/decline/pay». Для регулювання всього процесу самим надійним рішенням буде система з блокчейн-архітектурою.

Так у команди був певний бекграунд у розробці і дизайні, для back-end був обраний фреймворк Ruby on Rails (RoR), для front-end – JavaScript-фреймворк AngularJS.

З написанням смарт-контрактів було трохи складніше, так як ніхто з учасників раніше не стикався з подібним завданням. Тому була обрана платформа Ethereum (інструмент для створення децентралізованих онлайн-сервісів на базі блокчейна) на основі Azure Blockchain as a Service. Смарт-контракти програмувалися на спеціальному мовою Solidity.

Учасники поділилися двома питаннями, які виникли у них при роботі з цим інструментом, і відповідями на них.

Де зберігається контракт і хто забезпечує його коректне виконання?
Коли смарт-контракт написаний і налагоджений, він поміщається в ланцюжок блоків транзакцій, і може бути перевірений (але не змінено!) будь користувачем системи, якщо той знає адресу по якій розташований цей смарт-контракт. Коректність самого смарт-контракту залежить від того, наскільки коректно його написав програміст. Якщо смарт-контракт був описаний невірно, його не можна виправити і доведеться помістити інший смарт-контракт за іншою адресою.

Яка ціна створення смарт-контракту?
Для створення смарт-контракту потрібно витратити деяку кількість внутрішньої валюти (Eth), чим вище буде його ціна, тим вище він отримує пріоритет у майнер (це машини яких обчислюють криптоблоки). Майнеры потрібні для того, щоб смарт-контракт був оброблений і доданий в блокчейн. Якщо перший внесок буде мінімальним, може виникнути ситуація, в якій смарт-контракт ніколи не буде розміщено в глобальному блокчейне. Варто звернути увагу, що також можна задати час життя контракту.

Що потрібно знати для роботи з платформою Ethereum для клієнтської сторони

Насамперед, вам необхідно зрозуміти для якої платформи ви пишете. Як писали вище, у даному рішенні був використаний фреймворк AngularJS, тому вся логіка була поміщена в контролер, і там відбувалася вся робота з web3.js.

Примітка: у реальних умовах подібні операції краще тримати на захищеному сервері подалі від клієнта.

Далі необхідно ініціалізувати підключення до програми для зв'язку з блокчейном:

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider("http://адрес_сервера:8545"));
var accounts = web3.eth.accounts;

accounts
– це облікові записи, які задіяні у програмі підключення до блокчейну (в нашому випадку, це geth).

Тепер потрібна функція для того, щоб дізнатися баланс підключених токенів:

function getBalance(address){
var funds = web3.eth.getBalance(address);
return funds;
}

Спробуємо оплатити що-небудь через смарт-контракт за адресою contractAddress:

function pay (amount, myToken, password, token, contractAddress){
web3.personal.unlockAccount(myToken,password);
var contract = web3.eth.contract(abi).at(contractAddress);
var res = contract.initDoctor.sendTransaction(token, {from:myToken, value:web3.toWei(amount,'ether')});
alert("you dropped to system with easy "+token); 
}

Примітка: для простоти був заданий пароль у вигляді plain text, але в реальній системі так робити не можна.

Це основні функції, які необхідно знати для виклику смарт-контрактів. Подробиці можна дізнатися на офіційному сайті Ethereum.

Що потрібно знати для написання смарт-контракту на мові Solidity

Існують онлайн-компілятори, так і компілятори смарт-контрактів, що поставляються Etherium. В даному проекті вирішили використовувати цей редактор, так як він досить зручний і швидкий.



Далі в блокчейне для написання смарт-контракту був використаний код:

pragma solidity ^0.4.0;
contract Dental {
uint cadPrice = 10;
uint millPrice = 10;
uint digitizePrice = 10;

mapping (address => uint) doctor_balances;
mapping (address => uint) digitizer_balances;
mapping (address => uint)cad_balances;
mapping (address => uint) mill_balances;
mapping (address => uint) statuses; 
//0 -start,
//1 - digitizer initialized,
//2 - cad initialized,
//3 - mill initialized,
//4 - digitizer ready,
//5 - cad_ready,
//6 - mill ready,
//7 -payed
mapping (address => address) digitizer_addresses;
mapping (address => address) cad_addresses;
mapping (address => address) mill_addresses;

function initDoctor() { //Завантаження грошей
doctor_balances[ msg.sender ] += msg.value;
statuses[msg.sender] = 0;
}
function initDigitizer(address digitizerAddr) {
digitizer_addresses[msg.sender] = digitizerAddr;
digitizer_balances[msg.sender] += msg.value;
if (statuses[msg.sender] == 0) statuses[msg.sender] = 1;
}
function initCad(address cadAddr) {
cad_addresses[msg.sender] = cadAddr;
doctor_balances[ msg.sender ] -= cadPrice;
cad_balances[msg.sender] += msg.value;
if (statuses[msg.sender] == 1) statuses[msg.sender] = 1;
}
function initMill(address millAddr) {
mill_addresses[msg.sender] = millAddr;
mill_balances[msg.sender] += msg.value;
if (statuses[msg.sender] == 2) statuses[msg.sender] = 3;
}

function digitizerDone() {
if (statuses[msg.sender]==3) statuses[msg.sender] = 4;
}

function cadDone() {
if (statuses[msg.sender]==4) statuses[msg.sender] = 5;
}

function millDone() {
if (statuses[msg.sender]==5) statuses[msg.sender] = 6;
}

function doctorDone(bool happy) payable returns (bool) {
if (statuses[msg.sender]!=6) return false;
if (!happy){
doctor_balances[msg.sender] += digitizer_balances[msg.sender];
doctor_balances[msg.sender] += cad_balances[msg.sender];
doctor_balances[msg.sender] += mill_balances[msg.sender];
digitizer_balances[msg.sender] = 0;
cad_balances[msg.sender] = 0;
mill_balances[msg.sender] = 0;
return false;
}

bool digitizerOk = digitizer_addresses[msg.sender].send(digitizer_balances[msg.sender]);
digitizer_balances[msg.sender] = 0;
bool cadOk = cad_addresses[msg.sender].send(cad_balances[msg.sender]);
cad_balances[msg.sender] = 0;
bool millOk = mill_addresses[msg.sender].send(mill_balances[msg.sender]);
mill_balances[msg.sender] = 0;
return (digitizerOk && cadOk && millOk);
}
}

Розглянемо його докладніше:

1. Спочатку вказуємо версію Solidity і оголошуємо контракт:

pragma solidity ^0.4.0;
contract Dental {

2. задаємо вартість послуг 3D-сканування, дизайну і фрезерування:

uint cadPrice = 10;
uint millPrice = 10;
uint digitizePrice = 10;

3. Створюємо масиви балансів для оплати учасників процесу:

mapping (address => uint) doctor_balances;
mapping (address => uint) digitizer_balances;
mapping (address => uint) cad_balances;
mapping (address => uint) mill_balances;

4. Вказуємо статуси:

mapping (address => uint) statuses; 
//0 - start,
//1 - digitizer initialized,
//2 - cad initialized,
//3 - mill initialized,
//4 - digitizer ready,
//5 - cad_ready,
//6 - mill ready,
//7 -payed

5. Створюємо масиви облікових записів учасників процесу (без лікарів):

mapping (address => address) digitizer_addresses;
mapping (address => address) cad_addresses;
mapping (address => address) mill_addresses;

6. Ініціалізуємо лікаря, їм буде вважатися відправник. Зверніть увагу, що він може брати нові замовлення, тільки якщо у нього вказаний статус «ще не почав» або «замовлення завершений»:

function initDoctor() { //Завантаження грошей
if (statuses[msg.sender] == 0 || statuses[msg.sender] == 7){
doctor_balances[ msg.sender ] = msg.value;
statuses[msg.sender] = 0;
}
}


7. Ініціалізуємо сканировщика, який буде задіяний, якщо у лікаря стоїть статус «ще не почав»:

function initDigitizer(address digitizerAddr) {
digitizer_addresses[msg.sender] = digitizerAddr;
digitizer_balances[msg.sender] = msg.value;
if (statuses[msg.sender] == 0) statuses[msg.sender] = 1;
}

8. Аналогічно повторюємо з дизайном:

function initCad(address cadAddr) {
cad_addresses[msg.sender] = cadAddr;
doctor_balances[ msg.sender ] -= cadPrice;
cad_balances[msg.sender] = msg.value;
if (statuses[msg.sender] == 1) statuses[msg.sender] = 1;
}

9. Аналогічно повторюємо з фрезерувальником:

function initMill(address millAddr) {
mill_addresses[msg.sender] = millAddr;
mill_balances[msg.sender] += msg.value;
if (statuses[msg.sender] == 2) statuses[msg.sender] = 3;
}


10. Далі підтверджуємо роботу сканировщика:

function digitizerDone() {
if (statuses[msg.sender]==3) statuses[msg.sender] = 4;
}

11. Підтверджуємо роботу дизайнера:

function cadDone() {
if (statuses[msg.sender]==4) statuses[msg.sender] = 5;
}

12. Підтверджуємо роботу фрезерувальника:

function millDone() {
if (statuses[msg.sender]==5) statuses[msg.sender] = 6;
}

13. Лікар може прийняти або не прийняти роботу. В останньому випадку всі гроші будуть повернуті на його рахунок. ). Якщо робота ще не отфрезерована, то нічого не відбувається. Якщо лікар приймає роботу, гроші відправляються на рахунки учасників:

function doctorDone(bool happy) payable returns (bool) {
if (!happy){
doctor_balances[msg.sender] += digitizer_balances[msg.sender];
doctor_balances[msg.sender] += cad_balances[msg.sender];
doctor_balances[msg.sender] += mill_balances[msg.sender];
digitizer_balances[msg.sender] = 0;
cad_balances[msg.sender] = 0;
mill_balances[msg.sender] = 0;
return true;
}
if (statuses[msg.sender]!=6) return false; 
bool digitizerOk = digitizer_addresses[msg.sender].send(digitizer_balances[msg.sender]);
digitizer_balances[msg.sender] = 0;
bool cadOk = cad_addresses[msg.sender].send(cad_balances[msg.sender]);
cad_balances[msg.sender] = 0;
bool millOk = mill_addresses[msg.sender].send(mill_balances[msg.sender]);
mill_balances[msg.sender] = 0;
if (digitizerOk && cadOk && millOk) statuses[msg.sender]=7;
return (digitizerOk && cadOk && millOk);
}
}


Слово команді проекту Digital Dentistry Exchange
Ми запитали учасників проекту, яке майбутнє вони бачать у технології блокчейн:

«Технологія блокчейн – потенційно найкраща технологія для проведення транзакцій будь-яких типів, починаючи від фінансових послуг закінчуючи приготуванням їжі. Єдиним доповненням до блокчейну повинен бути допрацьований механізм proof-of-work, який буде приносити користь людям або науки (наприклад, давня завдання пошуку цілих значень параметрів a,b,c у виразі a^3+b^3+c^3=33).

На даний момент система блокчейна може бути ідеально інтегрована в систему надання послуг, де результати можуть бути виміряні (комплексні послуги в медицині, виробництві, онлайн-продажах або досягнення певних показників і, можливо, судова арбітражна система).

Кількість можливих додатків може бути величезним – головне тестувати ідеї, реалізації і активно їх впроваджувати. Також було б не зайвим впровадження правового регулювання та стандарту ISO систем з архітектурою блокчейн.»

На фотографії нижче автори матеріалу: Костянтин Скобєльцин, Віталій Дементьєв, Рінат Хатипов, Айдар Нигматжанов, Роман Варнава.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.